Commit d33852c5 authored by dogmaphobic's avatar dogmaphobic

PX4FLOW Sensor Support.

parent a4742fdc
...@@ -271,7 +271,7 @@ HEADERS += \ ...@@ -271,7 +271,7 @@ HEADERS += \
src/ui/uas/UASMessageView.h \ src/ui/uas/UASMessageView.h \
src/MissionItem.h \ src/MissionItem.h \
src/AutoPilotPlugins/PX4/PX4AirframeLoader.h \ src/AutoPilotPlugins/PX4/PX4AirframeLoader.h \
src/QGCSettings.h src/QmlControls/QGCImageProvider.h \
WindowsBuild { WindowsBuild {
PRECOMPILED_HEADER += src/stable_headers.h PRECOMPILED_HEADER += src/stable_headers.h
...@@ -383,7 +383,7 @@ SOURCES += \ ...@@ -383,7 +383,7 @@ SOURCES += \
src/ui/uas/UASMessageView.cc \ src/ui/uas/UASMessageView.cc \
src/MissionItem.cc \ src/MissionItem.cc \
src/AutoPilotPlugins/PX4/PX4AirframeLoader.cc \ src/AutoPilotPlugins/PX4/PX4AirframeLoader.cc \
src/QGCSettings.cpp src/QmlControls/QGCImageProvider.cc \
!iOSBuild { !iOSBuild {
SOURCES += \ SOURCES += \
......
This diff is collapsed.
/*===================================================================== /*=====================================================================
QGroundControl Open Source Ground Control Station QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> (c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful, QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>. along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/ ======================================================================*/
/// @file /// @file
...@@ -30,7 +30,7 @@ QGCQmlWidgetHolder::QGCQmlWidgetHolder(const QString& title, QAction* action, QW ...@@ -30,7 +30,7 @@ QGCQmlWidgetHolder::QGCQmlWidgetHolder(const QString& title, QAction* action, QW
QGCDockWidget(title, action, parent) QGCDockWidget(title, action, parent)
{ {
_ui.setupUi(this); _ui.setupUi(this);
layout()->setContentsMargins(0,0,0,0); layout()->setContentsMargins(0,0,0,0);
if (action) { if (action) {
...@@ -69,6 +69,12 @@ QQuickItem* QGCQmlWidgetHolder::getRootObject(void) ...@@ -69,6 +69,12 @@ QQuickItem* QGCQmlWidgetHolder::getRootObject(void)
return _ui.qmlWidget->rootObject(); return _ui.qmlWidget->rootObject();
} }
QQmlEngine* QGCQmlWidgetHolder::getEngine()
{
return _ui.qmlWidget->engine();
}
void QGCQmlWidgetHolder::setResizeMode(QQuickWidget::ResizeMode resizeMode) void QGCQmlWidgetHolder::setResizeMode(QQuickWidget::ResizeMode resizeMode)
{ {
_ui.qmlWidget->setResizeMode(resizeMode); _ui.qmlWidget->setResizeMode(resizeMode);
......
/*===================================================================== /*=====================================================================
QGroundControl Open Source Ground Control Station QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> (c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful, QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>. along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/ ======================================================================*/
#ifndef QGCQmlWidgetHolder_h #ifndef QGCQmlWidgetHolder_h
...@@ -49,7 +49,7 @@ public: ...@@ -49,7 +49,7 @@ public:
// action = NULL // action = NULL
explicit QGCQmlWidgetHolder(const QString& title, QAction* action, QWidget *parent = 0); explicit QGCQmlWidgetHolder(const QString& title, QAction* action, QWidget *parent = 0);
~QGCQmlWidgetHolder(); ~QGCQmlWidgetHolder();
/// Sets the UAS into the widget which in turn will load facts into the context /// Sets the UAS into the widget which in turn will load facts into the context
void setAutoPilot(AutoPilotPlugin* autoPilot); void setAutoPilot(AutoPilotPlugin* autoPilot);
...@@ -58,13 +58,16 @@ public: ...@@ -58,13 +58,16 @@ public:
/// Get Root Object /// Get Root Object
QQuickItem* getRootObject(void); QQuickItem* getRootObject(void);
/// Get QML Engine
QQmlEngine* getEngine();
/// Sets the QML into the control. Will display errors message box if error occurs loading source. /// 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 /// @return true: source loaded, false: source not loaded, errors occured
bool setSource(const QUrl& qmlUrl); bool setSource(const QUrl& qmlUrl);
void setContextPropertyObject(const QString& name, QObject* object); void setContextPropertyObject(const QString& name, QObject* object);
/// Sets the resize mode for the QQuickWidget container /// Sets the resize mode for the QQuickWidget container
void setResizeMode(QQuickWidget::ResizeMode resizeMode); void setResizeMode(QQuickWidget::ResizeMode resizeMode);
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "AutoPilotPluginManager.h" #include "AutoPilotPluginManager.h"
#include "UASMessageHandler.h" #include "UASMessageHandler.h"
#include "FactSystem.h" #include "FactSystem.h"
#include "QGCImageProvider.h"
QGCToolbox::QGCToolbox(QGCApplication* app) QGCToolbox::QGCToolbox(QGCApplication* app)
: _firmwarePluginManager(NULL) : _firmwarePluginManager(NULL)
...@@ -45,6 +46,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app) ...@@ -45,6 +46,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app)
, _audioOutput(NULL) , _audioOutput(NULL)
, _uasMessageHandler(NULL) , _uasMessageHandler(NULL)
, _factSystem(NULL) , _factSystem(NULL)
, _imageProvider(NULL)
{ {
_firmwarePluginManager = new FirmwarePluginManager(app); _firmwarePluginManager = new FirmwarePluginManager(app);
_autopilotPluginManager = new AutoPilotPluginManager(app); _autopilotPluginManager = new AutoPilotPluginManager(app);
...@@ -57,6 +59,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app) ...@@ -57,6 +59,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app)
_joystickManager = new JoystickManager(app); _joystickManager = new JoystickManager(app);
_audioOutput = new GAudioOutput(app); _audioOutput = new GAudioOutput(app);
_uasMessageHandler = new UASMessageHandler(app); _uasMessageHandler = new UASMessageHandler(app);
_imageProvider = new QGCImageProvider(app);
_firmwarePluginManager->setToolbox(this); _firmwarePluginManager->setToolbox(this);
_autopilotPluginManager->setToolbox(this); _autopilotPluginManager->setToolbox(this);
...@@ -69,6 +72,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app) ...@@ -69,6 +72,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app)
_joystickManager->setToolbox(this); _joystickManager->setToolbox(this);
_audioOutput->setToolbox(this); _audioOutput->setToolbox(this);
_uasMessageHandler->setToolbox(this); _uasMessageHandler->setToolbox(this);
_imageProvider->setToolbox(this);
} }
QGCToolbox::~QGCToolbox() QGCToolbox::~QGCToolbox()
......
/*===================================================================== /*=====================================================================
QGroundControl Open Source Ground Control Station QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful, QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>. along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/ ======================================================================*/
#ifndef QGCToolbox_h #ifndef QGCToolbox_h
...@@ -38,6 +38,7 @@ class GAudioOutput; ...@@ -38,6 +38,7 @@ class GAudioOutput;
class FirmwarePluginManager; class FirmwarePluginManager;
class AutoPilotPluginManager; class AutoPilotPluginManager;
class FactSystem; class FactSystem;
class QGCImageProvider;
/// This is used to manage all of our top level services/tools /// This is used to manage all of our top level services/tools
class QGCToolbox { class QGCToolbox {
...@@ -46,29 +47,31 @@ public: ...@@ -46,29 +47,31 @@ public:
QGCToolbox(QGCApplication* app); QGCToolbox(QGCApplication* app);
~QGCToolbox(); ~QGCToolbox();
LinkManager* linkManager(void) { return _linkManager; } LinkManager* linkManager(void) { return _linkManager; }
MAVLinkProtocol* mavlinkProtocol(void) { return _mavlinkProtocol; } MAVLinkProtocol* mavlinkProtocol(void) { return _mavlinkProtocol; }
MultiVehicleManager* multiVehicleManager(void) { return _multiVehicleManager; } MultiVehicleManager* multiVehicleManager(void) { return _multiVehicleManager; }
JoystickManager* joystickManager(void) { return _joystickManager; } JoystickManager* joystickManager(void) { return _joystickManager; }
UASMessageHandler* uasMessageHandler(void) { return _uasMessageHandler; } UASMessageHandler* uasMessageHandler(void) { return _uasMessageHandler; }
HomePositionManager* homePositionManager(void) { return _homePositionManager; } HomePositionManager* homePositionManager(void) { return _homePositionManager; }
FlightMapSettings* flightMapSettings(void) { return _flightMapSettings; } FlightMapSettings* flightMapSettings(void) { return _flightMapSettings; }
GAudioOutput* audioOutput(void) { return _audioOutput; } GAudioOutput* audioOutput(void) { return _audioOutput; }
FirmwarePluginManager* firmwarePluginManager(void) { return _firmwarePluginManager; } FirmwarePluginManager* firmwarePluginManager(void) { return _firmwarePluginManager; }
AutoPilotPluginManager* autopilotPluginManager(void) { return _autopilotPluginManager; } AutoPilotPluginManager* autopilotPluginManager(void) { return _autopilotPluginManager; }
QGCImageProvider* imageProvider() { return _imageProvider; }
private: private:
FirmwarePluginManager* _firmwarePluginManager; FirmwarePluginManager* _firmwarePluginManager;
AutoPilotPluginManager* _autopilotPluginManager; AutoPilotPluginManager* _autopilotPluginManager;
LinkManager* _linkManager; LinkManager* _linkManager;
MultiVehicleManager* _multiVehicleManager; MultiVehicleManager* _multiVehicleManager;
MAVLinkProtocol* _mavlinkProtocol; MAVLinkProtocol* _mavlinkProtocol;
FlightMapSettings* _flightMapSettings; FlightMapSettings* _flightMapSettings;
HomePositionManager* _homePositionManager; HomePositionManager* _homePositionManager;
JoystickManager* _joystickManager; JoystickManager* _joystickManager;
GAudioOutput* _audioOutput; GAudioOutput* _audioOutput;
UASMessageHandler* _uasMessageHandler; UASMessageHandler* _uasMessageHandler;
FactSystem* _factSystem; FactSystem* _factSystem;
QGCImageProvider* _imageProvider;
}; };
/// This is the base class for all tools /// This is the base class for all tools
......
...@@ -23,17 +23,75 @@ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>. ...@@ -23,17 +23,75 @@ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
/** /**
* @file * @file
* @brief Implementation of class QGCSettings * @brief Image Provider
* *
* @author Gus Grubba <mavlink@grubba.com> * @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 @@ ...@@ -23,28 +23,37 @@
/** /**
* @file * @file
* @brief Definition of main class * @brief Image Provider
* *
* @author Gus Grubba <mavlink@grubba.com> * @author Gus Grubba <mavlink@grubba.com>
* *
*/ */
#ifndef QGCSETTINGS_H #ifndef QGCIMAGEPROVIDER_H
#define QGCSETTINGS_H #define QGCIMAGEPROVIDER_H
#include <QObject> #include <QObject>
#include <QQmlListProperty>
#include <QQuickImageProvider>
class QGCSettings : public QObject #include "QGCToolbox.h"
class QGCImageProvider : public QGCTool, public QQuickImageProvider
{ {
Q_OBJECT
public: public:
explicit QGCSettings(QObject *parent = 0); QGCImageProvider (QGCApplication* app);
~QGCImageProvider ();
signals: QImage requestImage (const QString & id, QSize * size, const QSize & requestedSize);
void setImage (QImage* pImage, int id = 0);
public slots: 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 { ...@@ -39,6 +39,7 @@ Button {
verticalAlignment: TextEdit.AlignVCenter verticalAlignment: TextEdit.AlignVCenter
horizontalAlignment: TextEdit.AlignHCenter horizontalAlignment: TextEdit.AlignHCenter
color: showHighlight ? qgcPal.buttonHighlightText : qgcPal.buttonText color: showHighlight ? qgcPal.buttonHighlightText : qgcPal.buttonText
font.pixelSize: ScreenTools.isMobile ? ScreenTools.defaultFontPixelSize * 0.65 : ScreenTools.defaultFontPixelSize
text: control.text text: control.text
Rectangle { Rectangle {
......
/*===================================================================== /*=====================================================================
QGroundControl Open Source Ground Control Station QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> (c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful, QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>. along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/ ======================================================================*/
/// @file /// @file
...@@ -56,6 +56,7 @@ void MultiVehicleManager::setToolbox(QGCToolbox *toolbox) ...@@ -56,6 +56,7 @@ void MultiVehicleManager::setToolbox(QGCToolbox *toolbox)
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
qmlRegisterUncreatableType<MultiVehicleManager>("QGroundControl.MultiVehicleManager", 1, 0, "MultiVehicleManager", "Reference only"); qmlRegisterUncreatableType<MultiVehicleManager>("QGroundControl.MultiVehicleManager", 1, 0, "MultiVehicleManager", "Reference only");
} }
bool MultiVehicleManager::notifyHeartbeatInfo(LinkInterface* link, int vehicleId, mavlink_heartbeat_t& heartbeat) bool MultiVehicleManager::notifyHeartbeatInfo(LinkInterface* link, int vehicleId, mavlink_heartbeat_t& heartbeat)
...@@ -64,7 +65,7 @@ bool MultiVehicleManager::notifyHeartbeatInfo(LinkInterface* link, int vehicleId ...@@ -64,7 +65,7 @@ bool MultiVehicleManager::notifyHeartbeatInfo(LinkInterface* link, int vehicleId
if (vehicleId == _mavlinkProtocol->getSystemId()) { if (vehicleId == _mavlinkProtocol->getSystemId()) {
_app->showToolBarMessage(QString("Warning: A vehicle is using the same system id as QGroundControl: %1").arg(vehicleId)); _app->showToolBarMessage(QString("Warning: A vehicle is using the same system id as QGroundControl: %1").arg(vehicleId));
} }
QSettings settings; QSettings settings;
bool mavlinkVersionCheck = settings.value("VERSION_CHECK_ENABLED", true).toBool(); bool mavlinkVersionCheck = settings.value("VERSION_CHECK_ENABLED", true).toBool();
if (mavlinkVersionCheck && heartbeat.mavlink_version != MAVLINK_VERSION) { if (mavlinkVersionCheck && heartbeat.mavlink_version != MAVLINK_VERSION) {
...@@ -74,24 +75,24 @@ bool MultiVehicleManager::notifyHeartbeatInfo(LinkInterface* link, int vehicleId ...@@ -74,24 +75,24 @@ bool MultiVehicleManager::notifyHeartbeatInfo(LinkInterface* link, int vehicleId
"QGroundControl therefore refuses to connect to vehicle #%1, which sends MAVLink version %2 (QGroundControl uses version %3).").arg(vehicleId).arg(heartbeat.mavlink_version).arg(MAVLINK_VERSION)); "QGroundControl therefore refuses to connect to vehicle #%1, which sends MAVLink version %2 (QGroundControl uses version %3).").arg(vehicleId).arg(heartbeat.mavlink_version).arg(MAVLINK_VERSION));
return false; return false;
} }
Vehicle* vehicle = new Vehicle(link, vehicleId, (MAV_AUTOPILOT)heartbeat.autopilot, (MAV_TYPE)heartbeat.type, _firmwarePluginManager, _autopilotPluginManager, _joystickManager); Vehicle* vehicle = new Vehicle(link, vehicleId, (MAV_AUTOPILOT)heartbeat.autopilot, (MAV_TYPE)heartbeat.type, _firmwarePluginManager, _autopilotPluginManager, _joystickManager);
if (!vehicle) { if (!vehicle) {
qWarning() << "New Vehicle allocation failed"; qWarning() << "New Vehicle allocation failed";
return false; return false;
} }
connect(vehicle, &Vehicle::allLinksDisconnected, this, &MultiVehicleManager::_deleteVehiclePhase1); connect(vehicle, &Vehicle::allLinksDisconnected, this, &MultiVehicleManager::_deleteVehiclePhase1);
connect(vehicle->autopilotPlugin(), &AutoPilotPlugin::parametersReadyChanged, this, &MultiVehicleManager::_autopilotParametersReadyChanged); connect(vehicle->autopilotPlugin(), &AutoPilotPlugin::parametersReadyChanged, this, &MultiVehicleManager::_autopilotParametersReadyChanged);
_vehicles.append(vehicle); _vehicles.append(vehicle);
emit vehicleAdded(vehicle); emit vehicleAdded(vehicle);
setActiveVehicle(vehicle); setActiveVehicle(vehicle);
} }
return true; return true;
} }
...@@ -115,17 +116,17 @@ void MultiVehicleManager::_deleteVehiclePhase1(Vehicle* vehicle) ...@@ -115,17 +116,17 @@ void MultiVehicleManager::_deleteVehiclePhase1(Vehicle* vehicle)
if (!found) { if (!found) {
qWarning() << "Vehicle not found in map!"; qWarning() << "Vehicle not found in map!";
} }
vehicle->setActive(false); vehicle->setActive(false);
vehicle->uas()->clearVehicle(); vehicle->uas()->clearVehicle();
// First we must signal that a vehicle is no longer available. // First we must signal that a vehicle is no longer available.
_activeVehicleAvailable = false; _activeVehicleAvailable = false;
_parameterReadyVehicleAvailable = false; _parameterReadyVehicleAvailable = false;
emit activeVehicleAvailableChanged(false); emit activeVehicleAvailableChanged(false);
emit parameterReadyVehicleAvailableChanged(false); emit parameterReadyVehicleAvailableChanged(false);
emit vehicleRemoved(vehicle); emit vehicleRemoved(vehicle);
// We must let the above signals flow through the system as well as get back to the main loop event queue // We must let the above signals flow through the system as well as get back to the main loop event queue
// before we can actually delete the Vehicle. The reason is that Qml may be holding on the references to it. // before we can actually delete the Vehicle. The reason is that Qml may be holding on the references to it.
// Even though the above signals should unload any Qml which has references, that Qml will not be destroyed // Even though the above signals should unload any Qml which has references, that Qml will not be destroyed
...@@ -141,15 +142,15 @@ void MultiVehicleManager::_deleteVehiclePhase2 (void) ...@@ -141,15 +142,15 @@ void MultiVehicleManager::_deleteVehiclePhase2 (void)
/// Qml has been notified of vehicle about to go away and should be disconnected from it by now. /// Qml has been notified of vehicle about to go away and should be disconnected from it by now.
/// This means we can now clear the active vehicle property and delete the Vehicle for real. /// This means we can now clear the active vehicle property and delete the Vehicle for real.
Vehicle* newActiveVehicle = NULL; Vehicle* newActiveVehicle = NULL;
if (_vehicles.count()) { if (_vehicles.count()) {
newActiveVehicle = qobject_cast<Vehicle*>(_vehicles[0]); newActiveVehicle = qobject_cast<Vehicle*>(_vehicles[0]);
} }
_activeVehicle = newActiveVehicle; _activeVehicle = newActiveVehicle;
emit activeVehicleChanged(newActiveVehicle); emit activeVehicleChanged(newActiveVehicle);
if (_activeVehicle) { if (_activeVehicle) {
_activeVehicle->setActive(true); _activeVehicle->setActive(true);
emit activeVehicleAvailableChanged(true); emit activeVehicleAvailableChanged(true);
...@@ -157,7 +158,7 @@ void MultiVehicleManager::_deleteVehiclePhase2 (void) ...@@ -157,7 +158,7 @@ void MultiVehicleManager::_deleteVehiclePhase2 (void)
emit parameterReadyVehicleAvailableChanged(true); emit parameterReadyVehicleAvailableChanged(true);
} }
} }
_vehicleBeingDeleted->deleteLater(); _vehicleBeingDeleted->deleteLater();
} }
...@@ -168,10 +169,10 @@ void MultiVehicleManager::setActiveVehicle(Vehicle* vehicle) ...@@ -168,10 +169,10 @@ void MultiVehicleManager::setActiveVehicle(Vehicle* vehicle)
if (vehicle != _activeVehicle) { if (vehicle != _activeVehicle) {
if (_activeVehicle) { if (_activeVehicle) {
_activeVehicle->setActive(false); _activeVehicle->setActive(false);
// The sequence of signals is very important in order to not leave Qml elements connected // The sequence of signals is very important in order to not leave Qml elements connected
// to a non-existent vehicle. // to a non-existent vehicle.
// First we must signal that there is no active vehicle available. This will disconnect // First we must signal that there is no active vehicle available. This will disconnect
// any existing ui from the currently active vehicle. // any existing ui from the currently active vehicle.
_activeVehicleAvailable = false; _activeVehicleAvailable = false;
...@@ -179,7 +180,7 @@ void MultiVehicleManager::setActiveVehicle(Vehicle* vehicle) ...@@ -179,7 +180,7 @@ void MultiVehicleManager::setActiveVehicle(Vehicle* vehicle)
emit activeVehicleAvailableChanged(false); emit activeVehicleAvailableChanged(false);
emit parameterReadyVehicleAvailableChanged(false); emit parameterReadyVehicleAvailableChanged(false);
} }
// See explanation in _deleteVehiclePhase1 // See explanation in _deleteVehiclePhase1
_vehicleBeingSetActive = vehicle; _vehicleBeingSetActive = vehicle;
QTimer::singleShot(20, this, &MultiVehicleManager::_setActiveVehiclePhase2); QTimer::singleShot(20, this, &MultiVehicleManager::_setActiveVehiclePhase2);
...@@ -193,13 +194,13 @@ void MultiVehicleManager::_setActiveVehiclePhase2(void) ...@@ -193,13 +194,13 @@ void MultiVehicleManager::_setActiveVehiclePhase2(void)
// Now we signal the new active vehicle // Now we signal the new active vehicle
_activeVehicle = _vehicleBeingSetActive; _activeVehicle = _vehicleBeingSetActive;
emit activeVehicleChanged(_activeVehicle); emit activeVehicleChanged(_activeVehicle);
// And finally vehicle availability // And finally vehicle availability
if (_activeVehicle) { if (_activeVehicle) {
_activeVehicle->setActive(true); _activeVehicle->setActive(true);
_activeVehicleAvailable = true; _activeVehicleAvailable = true;
emit activeVehicleAvailableChanged(true); emit activeVehicleAvailableChanged(true);
if (_activeVehicle->autopilotPlugin()->parametersReady()) { if (_activeVehicle->autopilotPlugin()->parametersReady()) {
_parameterReadyVehicleAvailable = true; _parameterReadyVehicleAvailable = true;
emit parameterReadyVehicleAvailableChanged(true); emit parameterReadyVehicleAvailableChanged(true);
...@@ -210,12 +211,12 @@ void MultiVehicleManager::_setActiveVehiclePhase2(void) ...@@ -210,12 +211,12 @@ void MultiVehicleManager::_setActiveVehiclePhase2(void)
void MultiVehicleManager::_autopilotParametersReadyChanged(bool parametersReady) void MultiVehicleManager::_autopilotParametersReadyChanged(bool parametersReady)
{ {
AutoPilotPlugin* autopilot = dynamic_cast<AutoPilotPlugin*>(sender()); AutoPilotPlugin* autopilot = dynamic_cast<AutoPilotPlugin*>(sender());
if (!autopilot) { if (!autopilot) {
qWarning() << "Dynamic cast failed!"; qWarning() << "Dynamic cast failed!";
return; return;
} }
if (autopilot->vehicle() == _activeVehicle) { if (autopilot->vehicle() == _activeVehicle) {
_parameterReadyVehicleAvailable = parametersReady; _parameterReadyVehicleAvailable = parametersReady;
emit parameterReadyVehicleAvailableChanged(parametersReady); emit parameterReadyVehicleAvailableChanged(parametersReady);
...@@ -249,10 +250,12 @@ Vehicle* MultiVehicleManager::getVehicleById(int vehicleId) ...@@ -249,10 +250,12 @@ Vehicle* MultiVehicleManager::getVehicleById(int vehicleId)
QList<Vehicle*> MultiVehicleManager::vehicles(void) QList<Vehicle*> MultiVehicleManager::vehicles(void)
{ {
QList<Vehicle*> list; QList<Vehicle*> list;
for (int i=0; i< _vehicles.count(); i++) { for (int i=0; i< _vehicles.count(); i++) {
list += qobject_cast<Vehicle*>(_vehicles[i]); list += qobject_cast<Vehicle*>(_vehicles[i]);
} }
return list; return list;
} }
/*===================================================================== /*=====================================================================
QGroundControl Open Source Ground Control Station QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> (c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful, QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>. along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/ ======================================================================*/
/// @file /// @file
...@@ -44,20 +44,20 @@ Q_DECLARE_LOGGING_CATEGORY(MultiVehicleManagerLog) ...@@ -44,20 +44,20 @@ Q_DECLARE_LOGGING_CATEGORY(MultiVehicleManagerLog)
class MultiVehicleManager : public QGCTool class MultiVehicleManager : public QGCTool
{ {
Q_OBJECT Q_OBJECT
public: public:
MultiVehicleManager(QGCApplication* app); MultiVehicleManager(QGCApplication* app);
Q_INVOKABLE void saveSetting (const QString &key, const QString& value); Q_INVOKABLE void saveSetting (const QString &key, const QString& value);
Q_INVOKABLE QString loadSetting (const QString &key, const QString& defaultValue); Q_INVOKABLE QString loadSetting (const QString &key, const QString& defaultValue);
Q_PROPERTY(bool activeVehicleAvailable READ activeVehicleAvailable NOTIFY activeVehicleAvailableChanged) Q_PROPERTY(bool activeVehicleAvailable READ activeVehicleAvailable NOTIFY activeVehicleAvailableChanged)
Q_PROPERTY(bool parameterReadyVehicleAvailable READ parameterReadyVehicleAvailable NOTIFY parameterReadyVehicleAvailableChanged) Q_PROPERTY(bool parameterReadyVehicleAvailable READ parameterReadyVehicleAvailable NOTIFY parameterReadyVehicleAvailableChanged)
Q_PROPERTY(Vehicle* activeVehicle READ activeVehicle WRITE setActiveVehicle NOTIFY activeVehicleChanged) Q_PROPERTY(Vehicle* activeVehicle READ activeVehicle WRITE setActiveVehicle NOTIFY activeVehicleChanged)
Q_PROPERTY(QmlObjectListModel* vehicles READ vehiclesModel CONSTANT) Q_PROPERTY(QmlObjectListModel* vehicles READ vehiclesModel CONSTANT)
// Methods // Methods
/// Called to notify that a heartbeat was received with the specified information. MultiVehicleManager /// Called to notify that a heartbeat was received with the specified information. MultiVehicleManager
/// will create/update Vehicles as necessary. /// will create/update Vehicles as necessary.
/// @param link Heartbeat came through on this link /// @param link Heartbeat came through on this link
...@@ -65,24 +65,24 @@ public: ...@@ -65,24 +65,24 @@ public:
/// @param heartbeat Mavlink heartbeat message /// @param heartbeat Mavlink heartbeat message
/// @return true: continue further processing of this message, false: disregard this message /// @return true: continue further processing of this message, false: disregard this message
bool notifyHeartbeatInfo(LinkInterface* link, int vehicleId, mavlink_heartbeat_t& heartbeat); bool notifyHeartbeatInfo(LinkInterface* link, int vehicleId, mavlink_heartbeat_t& heartbeat);
Q_INVOKABLE Vehicle* getVehicleById(int vehicleId); Q_INVOKABLE Vehicle* getVehicleById(int vehicleId);
UAS* activeUas(void) { return _activeVehicle ? _activeVehicle->uas() : NULL; } UAS* activeUas(void) { return _activeVehicle ? _activeVehicle->uas() : NULL; }
QList<Vehicle*> vehicles(void); QList<Vehicle*> vehicles(void);
// Property accessors // Property accessors
bool activeVehicleAvailable(void) { return _activeVehicleAvailable; } bool activeVehicleAvailable(void) { return _activeVehicleAvailable; }
bool parameterReadyVehicleAvailable(void) { return _parameterReadyVehicleAvailable; } bool parameterReadyVehicleAvailable(void) { return _parameterReadyVehicleAvailable; }
Vehicle* activeVehicle(void) { return _activeVehicle; } Vehicle* activeVehicle(void) { return _activeVehicle; }
void setActiveVehicle(Vehicle* vehicle); void setActiveVehicle(Vehicle* vehicle);
QmlObjectListModel* vehiclesModel(void) { return &_vehicles; } QmlObjectListModel* vehiclesModel(void) { return &_vehicles; }
// Override from QGCTool // Override from QGCTool
virtual void setToolbox(QGCToolbox *toolbox); virtual void setToolbox(QGCToolbox *toolbox);
...@@ -92,33 +92,34 @@ signals: ...@@ -92,33 +92,34 @@ signals:
void activeVehicleAvailableChanged(bool activeVehicleAvailable); void activeVehicleAvailableChanged(bool activeVehicleAvailable);
void parameterReadyVehicleAvailableChanged(bool parameterReadyVehicleAvailable); void parameterReadyVehicleAvailableChanged(bool parameterReadyVehicleAvailable);
void activeVehicleChanged(Vehicle* activeVehicle); void activeVehicleChanged(Vehicle* activeVehicle);
void _deleteVehiclePhase2Signal(void); void _deleteVehiclePhase2Signal(void);
private slots: private slots:
void _deleteVehiclePhase1(Vehicle* vehicle); void _deleteVehiclePhase1(Vehicle* vehicle);
void _deleteVehiclePhase2(void); void _deleteVehiclePhase2(void);
void _setActiveVehiclePhase2(void); void _setActiveVehiclePhase2(void);
void _autopilotParametersReadyChanged(bool parametersReady); void _autopilotParametersReadyChanged(bool parametersReady);
private: private:
bool _vehicleExists(int vehicleId); bool _vehicleExists(int vehicleId);
bool _activeVehicleAvailable; ///< true: An active vehicle is available bool _activeVehicleAvailable; ///< true: An active vehicle is available
bool _parameterReadyVehicleAvailable; ///< true: An active vehicle with ready parameters is available bool _parameterReadyVehicleAvailable; ///< true: An active vehicle with ready parameters is available
Vehicle* _activeVehicle; ///< Currently active vehicle from a ui perspective Vehicle* _activeVehicle; ///< Currently active vehicle from a ui perspective
Vehicle* _vehicleBeingDeleted; ///< Vehicle being deleted in queued phases Vehicle* _vehicleBeingDeleted; ///< Vehicle being deleted in queued phases
Vehicle* _vehicleBeingSetActive; ///< Vehicle being set active in queued phases Vehicle* _vehicleBeingSetActive; ///< Vehicle being set active in queued phases
QList<int> _ignoreVehicleIds; ///< List of vehicle id for which we ignore further communication QList<int> _ignoreVehicleIds; ///< List of vehicle id for which we ignore further communication
QmlObjectListModel _vehicles; QmlObjectListModel _vehicles;
FirmwarePluginManager* _firmwarePluginManager; FirmwarePluginManager* _firmwarePluginManager;
AutoPilotPluginManager* _autopilotPluginManager; AutoPilotPluginManager* _autopilotPluginManager;
JoystickManager* _joystickManager; JoystickManager* _joystickManager;
MAVLinkProtocol* _mavlinkProtocol; MAVLinkProtocol* _mavlinkProtocol;
}; };
#endif #endif
This diff is collapsed.
This diff is collapsed.
/*=====================================================================
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 { ...@@ -94,6 +94,11 @@ Rectangle {
panelLoader.source = "SetupParameterEditor.qml"; panelLoader.source = "SetupParameterEditor.qml";
} }
function showPX4FlowPanel()
{
panelLoader.source = "PX4FlowSensor.qml";
}
function showVehicleComponentPanel(vehicleComponent) function showVehicleComponentPanel(vehicleComponent)
{ {
if (multiVehicleManager.activeVehicle.armed) { if (multiVehicleManager.activeVehicle.armed) {
...@@ -247,6 +252,16 @@ Rectangle { ...@@ -247,6 +252,16 @@ Rectangle {
onClicked: showFirmwarePanel() onClicked: showFirmwarePanel()
} }
SubMenuButton {
id: px4FlowButton
width: mainWindow.menuButtonWidth
exclusiveGroup: setupButtonGroup
visible: _fullParameterVehicleAvailable
setupIndicator: false
text: "PX4FLOW"
onClicked: showPX4FlowPanel()
}
SubMenuButton { SubMenuButton {
id: joystickButton id: joystickButton
width: mainWindow.menuButtonWidth width: mainWindow.menuButtonWidth
......
...@@ -70,7 +70,7 @@ union px4_custom_mode { ...@@ -70,7 +70,7 @@ union px4_custom_mode {
float MockLink::_vehicleLatitude = 47.633033f; float MockLink::_vehicleLatitude = 47.633033f;
float MockLink::_vehicleLongitude = -122.08794f; float MockLink::_vehicleLongitude = -122.08794f;
float MockLink::_vehicleAltitude = 2.5f; float MockLink::_vehicleAltitude = 9872.5f;
const char* MockConfiguration::_firmwareTypeKey = "FirmwareType"; const char* MockConfiguration::_firmwareTypeKey = "FirmwareType";
const char* MockConfiguration::_vehicleTypeKey = "VehicleType"; const char* MockConfiguration::_vehicleTypeKey = "VehicleType";
...@@ -108,9 +108,9 @@ MockLink::MockLink(MockConfiguration* config) ...@@ -108,9 +108,9 @@ MockLink::MockLink(MockConfiguration* config)
_fileServer = new MockLinkFileServer(_vehicleSystemId, _vehicleComponentId, this); _fileServer = new MockLinkFileServer(_vehicleSystemId, _vehicleComponentId, this);
Q_CHECK_PTR(_fileServer); Q_CHECK_PTR(_fileServer);
moveToThread(this); moveToThread(this);
_loadParams(); _loadParams();
QObject::connect(this, &MockLink::_incomingBytes, this, &MockLink::_handleIncomingBytes); QObject::connect(this, &MockLink::_incomingBytes, this, &MockLink::_handleIncomingBytes);
} }
...@@ -154,7 +154,7 @@ void MockLink::run(void) ...@@ -154,7 +154,7 @@ void MockLink::run(void)
QTimer _timer10HzTasks; QTimer _timer10HzTasks;
QTimer _timer50HzTasks; QTimer _timer50HzTasks;
QObject::connect(&_timer1HzTasks, &QTimer::timeout, this, &MockLink::_run1HzTasks); QObject::connect(&_timer1HzTasks, &QTimer::timeout, this, &MockLink::_run1HzTasks);
QObject::connect(&_timer10HzTasks, &QTimer::timeout, this, &MockLink::_run10HzTasks); QObject::connect(&_timer10HzTasks, &QTimer::timeout, this, &MockLink::_run10HzTasks);
QObject::connect(&_timer50HzTasks, &QTimer::timeout, this, &MockLink::_run50HzTasks); QObject::connect(&_timer50HzTasks, &QTimer::timeout, this, &MockLink::_run50HzTasks);
...@@ -164,10 +164,10 @@ void MockLink::run(void) ...@@ -164,10 +164,10 @@ void MockLink::run(void)
exec(); exec();
QObject::disconnect(&_timer1HzTasks, &QTimer::timeout, this, &MockLink::_run1HzTasks); QObject::disconnect(&_timer1HzTasks, &QTimer::timeout, this, &MockLink::_run1HzTasks);
QObject::disconnect(&_timer10HzTasks, &QTimer::timeout, this, &MockLink::_run10HzTasks); QObject::disconnect(&_timer10HzTasks, &QTimer::timeout, this, &MockLink::_run10HzTasks);
QObject::disconnect(&_timer50HzTasks, &QTimer::timeout, this, &MockLink::_run50HzTasks); QObject::disconnect(&_timer50HzTasks, &QTimer::timeout, this, &MockLink::_run50HzTasks);
_missionItemHandler.shutdown(); _missionItemHandler.shutdown();
} }
...@@ -285,14 +285,14 @@ void MockLink::_sendHeartBeat(void) ...@@ -285,14 +285,14 @@ void MockLink::_sendHeartBeat(void)
_mavBaseMode, // MAV_MODE _mavBaseMode, // MAV_MODE
_mavCustomMode, // custom mode _mavCustomMode, // custom mode
_mavState); // MAV_STATE _mavState); // MAV_STATE
respondWithMavlinkMessage(msg); respondWithMavlinkMessage(msg);
} }
void MockLink::respondWithMavlinkMessage(const mavlink_message_t& msg) void MockLink::respondWithMavlinkMessage(const mavlink_message_t& msg)
{ {
uint8_t buffer[MAVLINK_MAX_PACKET_LEN]; uint8_t buffer[MAVLINK_MAX_PACKET_LEN];
int cBuffer = mavlink_msg_to_send_buffer(buffer, &msg); int cBuffer = mavlink_msg_to_send_buffer(buffer, &msg);
QByteArray bytes((char *)buffer, cBuffer); QByteArray bytes((char *)buffer, cBuffer);
emit bytesReceived(this, bytes); emit bytesReceived(this, bytes);
...@@ -354,7 +354,7 @@ void MockLink::_handleIncomingMavlinkBytes(const uint8_t* bytes, int cBytes) ...@@ -354,7 +354,7 @@ void MockLink::_handleIncomingMavlinkBytes(const uint8_t* bytes, int cBytes)
if (!mavlink_parse_char(getMavlinkChannel(), bytes[i], &msg, &comm)) { if (!mavlink_parse_char(getMavlinkChannel(), bytes[i], &msg, &comm)) {
continue; continue;
} }
if (_missionItemHandler.handleMessage(msg)) { if (_missionItemHandler.handleMessage(msg)) {
continue; continue;
} }
...@@ -379,11 +379,11 @@ void MockLink::_handleIncomingMavlinkBytes(const uint8_t* bytes, int cBytes) ...@@ -379,11 +379,11 @@ void MockLink::_handleIncomingMavlinkBytes(const uint8_t* bytes, int cBytes)
case MAVLINK_MSG_ID_PARAM_REQUEST_READ: case MAVLINK_MSG_ID_PARAM_REQUEST_READ:
_handleParamRequestRead(msg); _handleParamRequestRead(msg);
break; break;
case MAVLINK_MSG_ID_FILE_TRANSFER_PROTOCOL: case MAVLINK_MSG_ID_FILE_TRANSFER_PROTOCOL:
_handleFTP(msg); _handleFTP(msg);
break; break;
case MAVLINK_MSG_ID_COMMAND_LONG: case MAVLINK_MSG_ID_COMMAND_LONG:
_handleCommandLong(msg); _handleCommandLong(msg);
break; break;
...@@ -552,14 +552,14 @@ void MockLink::_handleParamRequestList(const mavlink_message_t& msg) ...@@ -552,14 +552,14 @@ void MockLink::_handleParamRequestList(const mavlink_message_t& msg)
Q_ASSERT(request.target_system == _vehicleSystemId); Q_ASSERT(request.target_system == _vehicleSystemId);
Q_ASSERT(request.target_component == MAV_COMP_ID_ALL); Q_ASSERT(request.target_component == MAV_COMP_ID_ALL);
// We must send the first parameter for each component first. Otherwise system won't correctly know // We must send the first parameter for each component first. Otherwise system won't correctly know
// when all parameters are loaded. // when all parameters are loaded.
foreach (int componentId, _mapParamName2Value.keys()) { foreach (int componentId, _mapParamName2Value.keys()) {
uint16_t paramIndex = 0; uint16_t paramIndex = 0;
int cParameters = _mapParamName2Value[componentId].count(); int cParameters = _mapParamName2Value[componentId].count();
foreach(QString paramName, _mapParamName2Value[componentId].keys()) { foreach(QString paramName, _mapParamName2Value[componentId].keys()) {
char paramId[MAVLINK_MSG_ID_PARAM_VALUE_LEN]; char paramId[MAVLINK_MSG_ID_PARAM_VALUE_LEN];
mavlink_message_t responseMsg; mavlink_message_t responseMsg;
...@@ -583,17 +583,17 @@ void MockLink::_handleParamRequestList(const mavlink_message_t& msg) ...@@ -583,17 +583,17 @@ void MockLink::_handleParamRequestList(const mavlink_message_t& msg)
cParameters, // Total number of parameters cParameters, // Total number of parameters
paramIndex++); // Index of this parameter paramIndex++); // Index of this parameter
respondWithMavlinkMessage(responseMsg); respondWithMavlinkMessage(responseMsg);
// Only first parameter the first time through // Only first parameter the first time through
break; break;
} }
} }
foreach (int componentId, _mapParamName2Value.keys()) { foreach (int componentId, _mapParamName2Value.keys()) {
uint16_t paramIndex = 0; uint16_t paramIndex = 0;
int cParameters = _mapParamName2Value[componentId].count(); int cParameters = _mapParamName2Value[componentId].count();
bool skipParam = true; bool skipParam = true;
foreach(QString paramName, _mapParamName2Value[componentId].keys()) { foreach(QString paramName, _mapParamName2Value[componentId].keys()) {
if (skipParam) { if (skipParam) {
// We've already sent the first param // We've already sent the first param
...@@ -602,17 +602,17 @@ void MockLink::_handleParamRequestList(const mavlink_message_t& msg) ...@@ -602,17 +602,17 @@ void MockLink::_handleParamRequestList(const mavlink_message_t& msg)
} else { } else {
char paramId[MAVLINK_MSG_ID_PARAM_VALUE_LEN]; char paramId[MAVLINK_MSG_ID_PARAM_VALUE_LEN];
mavlink_message_t responseMsg; mavlink_message_t responseMsg;
Q_ASSERT(_mapParamName2Value[componentId].contains(paramName)); Q_ASSERT(_mapParamName2Value[componentId].contains(paramName));
Q_ASSERT(_mapParamName2MavParamType.contains(paramName)); Q_ASSERT(_mapParamName2MavParamType.contains(paramName));
MAV_PARAM_TYPE paramType = _mapParamName2MavParamType[paramName]; MAV_PARAM_TYPE paramType = _mapParamName2MavParamType[paramName];
Q_ASSERT(paramName.length() <= MAVLINK_MSG_ID_PARAM_VALUE_LEN); Q_ASSERT(paramName.length() <= MAVLINK_MSG_ID_PARAM_VALUE_LEN);
strncpy(paramId, paramName.toLocal8Bit().constData(), MAVLINK_MSG_ID_PARAM_VALUE_LEN); strncpy(paramId, paramName.toLocal8Bit().constData(), MAVLINK_MSG_ID_PARAM_VALUE_LEN);
qCDebug(MockLinkLog) << "Sending msg_param_value" << componentId << paramId << paramType << _mapParamName2Value[componentId][paramId]; qCDebug(MockLinkLog) << "Sending msg_param_value" << componentId << paramId << paramType << _mapParamName2Value[componentId][paramId];
mavlink_msg_param_value_pack(_vehicleSystemId, mavlink_msg_param_value_pack(_vehicleSystemId,
componentId, // component id componentId, // component id
&responseMsg, // Outgoing message &responseMsg, // Outgoing message
...@@ -634,14 +634,14 @@ void MockLink::_handleParamSet(const mavlink_message_t& msg) ...@@ -634,14 +634,14 @@ void MockLink::_handleParamSet(const mavlink_message_t& msg)
Q_ASSERT(request.target_system == _vehicleSystemId); Q_ASSERT(request.target_system == _vehicleSystemId);
int componentId = request.target_component; int componentId = request.target_component;
// Param may not be null terminated if exactly fits // Param may not be null terminated if exactly fits
char paramId[MAVLINK_MSG_PARAM_SET_FIELD_PARAM_ID_LEN + 1]; char paramId[MAVLINK_MSG_PARAM_SET_FIELD_PARAM_ID_LEN + 1];
paramId[MAVLINK_MSG_PARAM_SET_FIELD_PARAM_ID_LEN] = 0; paramId[MAVLINK_MSG_PARAM_SET_FIELD_PARAM_ID_LEN] = 0;
strncpy(paramId, request.param_id, MAVLINK_MSG_PARAM_SET_FIELD_PARAM_ID_LEN); strncpy(paramId, request.param_id, MAVLINK_MSG_PARAM_SET_FIELD_PARAM_ID_LEN);
qCDebug(MockLinkLog) << "_handleParamSet" << componentId << paramId << request.param_type; qCDebug(MockLinkLog) << "_handleParamSet" << componentId << paramId << request.param_type;
Q_ASSERT(_mapParamName2Value.contains(componentId)); Q_ASSERT(_mapParamName2Value.contains(componentId));
Q_ASSERT(_mapParamName2Value[componentId].contains(paramId)); Q_ASSERT(_mapParamName2Value[componentId].contains(paramId));
Q_ASSERT(request.param_type == _mapParamName2MavParamType[paramId]); Q_ASSERT(request.param_type == _mapParamName2MavParamType[paramId]);
...@@ -726,12 +726,12 @@ void MockLink::_handleParamRequestRead(const mavlink_message_t& msg) ...@@ -726,12 +726,12 @@ void MockLink::_handleParamRequestRead(const mavlink_message_t& msg)
void MockLink::emitRemoteControlChannelRawChanged(int channel, uint16_t raw) void MockLink::emitRemoteControlChannelRawChanged(int channel, uint16_t raw)
{ {
uint16_t chanRaw[18]; uint16_t chanRaw[18];
for (int i=0; i<18; i++) { for (int i=0; i<18; i++) {
chanRaw[i] = UINT16_MAX; chanRaw[i] = UINT16_MAX;
} }
chanRaw[channel] = raw; chanRaw[channel] = raw;
mavlink_message_t responseMsg; mavlink_message_t responseMsg;
mavlink_msg_rc_channels_pack(_vehicleSystemId, mavlink_msg_rc_channels_pack(_vehicleSystemId,
_vehicleComponentId, _vehicleComponentId,
...@@ -769,7 +769,7 @@ void MockLink::_handleFTP(const mavlink_message_t& msg) ...@@ -769,7 +769,7 @@ void MockLink::_handleFTP(const mavlink_message_t& msg)
void MockLink::_handleCommandLong(const mavlink_message_t& msg) void MockLink::_handleCommandLong(const mavlink_message_t& msg)
{ {
mavlink_command_long_t request; mavlink_command_long_t request;
mavlink_msg_command_long_decode(&msg, &request); mavlink_msg_command_long_decode(&msg, &request);
if (request.command == MAV_CMD_COMPONENT_ARM_DISARM) { if (request.command == MAV_CMD_COMPONENT_ARM_DISARM) {
...@@ -808,7 +808,7 @@ void MockLink::_sendHomePosition(void) ...@@ -808,7 +808,7 @@ void MockLink::_sendHomePosition(void)
(int32_t)(_vehicleAltitude * 1000), (int32_t)(_vehicleAltitude * 1000),
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
&bogus[0], &bogus[0],
0.0f, 0.0f, 0.0f); 0.0f, 0.0f, 0.0f);
respondWithMavlinkMessage(msg); respondWithMavlinkMessage(msg);
} }
} }
...@@ -823,9 +823,9 @@ void MockLink::_sendGpsRawInt(void) ...@@ -823,9 +823,9 @@ void MockLink::_sendGpsRawInt(void)
&msg, &msg,
timeTick++, // time since boot timeTick++, // time since boot
3, // 3D fix 3, // 3D fix
(int32_t)(_vehicleLatitude * 1E7), (int32_t)(_vehicleLatitude * 1E7),
(int32_t)(_vehicleLongitude * 1E7), (int32_t)(_vehicleLongitude * 1E7),
(int32_t)(_vehicleAltitude * 1000), (int32_t)(_vehicleAltitude * 1000),
UINT16_MAX, UINT16_MAX, // HDOP/VDOP not known UINT16_MAX, UINT16_MAX, // HDOP/VDOP not known
UINT16_MAX, // velocity not known UINT16_MAX, // velocity not known
UINT16_MAX, // course over ground not known UINT16_MAX, // course over ground not known
...@@ -878,7 +878,7 @@ MockConfiguration::MockConfiguration(MockConfiguration* source) ...@@ -878,7 +878,7 @@ MockConfiguration::MockConfiguration(MockConfiguration* source)
: LinkConfiguration(source) : LinkConfiguration(source)
{ {
_firmwareType = source->_firmwareType; _firmwareType = source->_firmwareType;
_vehicleType = source->_vehicleType; _vehicleType = source->_vehicleType;
_sendStatusText = source->_sendStatusText; _sendStatusText = source->_sendStatusText;
} }
......
...@@ -53,6 +53,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -53,6 +53,7 @@ This file is part of the QGROUNDCONTROL project
#include "HomePositionManager.h" #include "HomePositionManager.h"
#include "LogCompressor.h" #include "LogCompressor.h"
#include "UAS.h" #include "UAS.h"
#include "QGCImageProvider.h"
#ifndef __mobile__ #ifndef __mobile__
#include "QGCDataPlot2D.h" #include "QGCDataPlot2D.h"
...@@ -166,6 +167,10 @@ MainWindow::MainWindow() ...@@ -166,6 +167,10 @@ MainWindow::MainWindow()
_mainQmlWidgetHolder->setContextPropertyObject("controller", this); _mainQmlWidgetHolder->setContextPropertyObject("controller", this);
_mainQmlWidgetHolder->setSource(QUrl::fromUserInput("qrc:qml/MainWindow.qml")); _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 // Set dock options
setDockOptions(0); setDockOptions(0);
// Setup corners // Setup corners
...@@ -309,6 +314,7 @@ MainWindow::MainWindow() ...@@ -309,6 +314,7 @@ MainWindow::MainWindow()
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
_mainQmlWidgetHolder->getEngine()->removeImageProvider(QLatin1String("QGCImages"));
_instance = NULL; _instance = NULL;
} }
...@@ -465,6 +471,8 @@ void MainWindow::closeEvent(QCloseEvent *event) ...@@ -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 // 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 // the MainWindow ends up getting deleted. Otherwise the Qml has a reference to MainWindow
// inside it which in turn causes a shutdown crash. // inside it which in turn causes a shutdown crash.
// Remove image provider
_mainQmlWidgetHolder->getEngine()->removeImageProvider(QLatin1String("QGCImages"));
_centralLayout->removeWidget(_mainQmlWidgetHolder); _centralLayout->removeWidget(_mainQmlWidgetHolder);
delete _mainQmlWidgetHolder; delete _mainQmlWidgetHolder;
_mainQmlWidgetHolder = NULL; _mainQmlWidgetHolder = NULL;
...@@ -474,7 +482,10 @@ void MainWindow::closeEvent(QCloseEvent *event) ...@@ -474,7 +482,10 @@ void MainWindow::closeEvent(QCloseEvent *event)
event->accept(); event->accept();
//-- TODO: This effectively causes the QGCApplication destructor to not being able
// to access the pointer it is trying to delete.
_instance = NULL; _instance = NULL;
emit mainWindowClosed(); 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