Commit c240c43e authored by Don Gagne's avatar Don Gagne

Use true list models for vehicles and mission items

parent d14444a5
...@@ -261,6 +261,7 @@ HEADERS += \ ...@@ -261,6 +261,7 @@ HEADERS += \
src/QmlControls/MavlinkQmlSingleton.h \ src/QmlControls/MavlinkQmlSingleton.h \
src/QmlControls/ParameterEditorController.h \ src/QmlControls/ParameterEditorController.h \
src/QmlControls/ScreenToolsController.h \ src/QmlControls/ScreenToolsController.h \
src/QmlControls/QmlObjectListModel.h \
src/SerialPortIds.h \ src/SerialPortIds.h \
src/uas/FileManager.h \ src/uas/FileManager.h \
src/uas/UAS.h \ src/uas/UAS.h \
...@@ -393,6 +394,7 @@ SOURCES += \ ...@@ -393,6 +394,7 @@ SOURCES += \
src/QGCTemporaryFile.cc \ src/QGCTemporaryFile.cc \
src/QmlControls/ParameterEditorController.cc \ src/QmlControls/ParameterEditorController.cc \
src/QmlControls/ScreenToolsController.cc \ src/QmlControls/ScreenToolsController.cc \
src/QmlControls/QmlObjectListModel.cc \
src/uas/FileManager.cc \ src/uas/FileManager.cc \
src/uas/UAS.cc \ src/uas/UAS.cc \
src/uas/UASMessageHandler.cc \ src/uas/UASMessageHandler.cc \
......
...@@ -27,10 +27,10 @@ This file is part of the QGROUNDCONTROL project ...@@ -27,10 +27,10 @@ This file is part of the QGROUNDCONTROL project
* @author Gus Grubba <mavlink@grubba.com> * @author Gus Grubba <mavlink@grubba.com>
*/ */
import QtQuick 2.4 import QtQuick 2.4
import QtQuick.Controls 1.3 import QtQuick.Controls 1.3
import QtLocation 5.3 import QtLocation 5.3
import QtPositioning 5.3 import QtPositioning 5.3
import QGroundControl.Controls 1.0 import QGroundControl.Controls 1.0
import QGroundControl.FlightMap 1.0 import QGroundControl.FlightMap 1.0
...@@ -58,18 +58,6 @@ Item { ...@@ -58,18 +58,6 @@ Item {
Component.onCompleted: { Component.onCompleted: {
map.zoomLevel = 18 map.zoomLevel = 18
mapTypeMenu.update(); mapTypeMenu.update();
addExistingVehicles()
updateMissionItemsConnections()
updateMissionItems()
}
function updateMapType(type) {
var isSatellite = (type === MapType.SatelliteMapDay || type === MapType.SatelliteMapNight)
if(isSatelliteMap !== isSatellite) {
isSatelliteMap = isSatellite;
removeAllVehicles()
addExistingVehicles()
}
} }
//-- Menu to select supported map types //-- Menu to select supported map types
...@@ -82,7 +70,6 @@ Item { ...@@ -82,7 +70,6 @@ Item {
for (var i = 0; i < map.supportedMapTypes.length; i++) { for (var i = 0; i < map.supportedMapTypes.length; i++) {
if (mapID === map.supportedMapTypes[i].name) { if (mapID === map.supportedMapTypes[i].name) {
map.activeMapType = map.supportedMapTypes[i] map.activeMapType = map.supportedMapTypes[i]
updateMapType(map.supportedMapTypes[i].style)
multiVehicleManager.saveSetting(root.mapName + "/currentMapType", mapID); multiVehicleManager.saveSetting(root.mapName + "/currentMapType", mapID);
return; return;
} }
...@@ -148,178 +135,6 @@ Item { ...@@ -148,178 +135,6 @@ Item {
} }
*/ */
// The following code is used to add and remove Vehicle markers from the map. Due to the following
// problems this code must be here is the base FlightMap control:
// - If you pass a reference to the Map control into another object and then try to call
// functions such as addMapItem on it, it will fail telling you addMapItem is not a function
// on that object
// - Due to the fact that you need to dynamically add the MapQuickItems, they need to be able
// to reference the Vehicle they are associated with in some way. In order to do that
// we need to keep a separate array of Vehicles which must be at the top level of the object
// hierarchy in order for the dynamically added object to see it.
property var _vehicles: [] ///< List of known vehicles
property var _vehicleMapItems: [] ///< List of known vehicle map items
Connections {
target: multiVehicleManager
onVehicleAdded: addVehicle(vehicle)
onVehicleRemoved: removeVehicle(vehicle)
}
function addVehicle(vehicle) {
if (!showVehicles) {
return
}
var qmlItemTemplate = "VehicleMapItem { " +
"coordinate: _vehicles[%1].coordinate; " +
"heading: _vehicles[%1].heading; " +
"isSatellite: root.isSatelliteMap; " +
"}"
var i = _vehicles.length
qmlItemTemplate = qmlItemTemplate.replace("%1", i)
qmlItemTemplate = qmlItemTemplate.replace("%1", i)
_vehicles.push(vehicle)
var mapItem = Qt.createQmlObject (qmlItemTemplate, map)
_vehicleMapItems.push(mapItem)
mapItem.z = map.z + 1
map.addMapItem(mapItem)
}
function removeVehicle(vehicle) {
if (!showVehicles) {
return
}
for (var i=0; i<_vehicles.length; i++) {
if (_vehicles[i] == vehicle) {
_vehicles[i] = undefined
map.removeMapItem(_vehicleMapItems[i])
_vehicleMapItems[i] = undefined
break
}
}
}
function removeAllVehicles() {
if (!showVehicles) {
return
}
for (var i=0; i<_vehicles.length; i++) {
_vehicles[i] = undefined
map.removeMapItem(_vehicleMapItems[i])
_vehicleMapItems[i] = undefined
}
}
function addExistingVehicles() {
if (!showVehicles) {
return
}
for (var i=0; i<multiVehicleManager.vehicles.length; i++) {
addVehicle(multiVehicleManager.vehicles[i])
}
}
// The following code is used to show mission items on the FlightMap
property var _missionItems: [] ///< List of known vehicles
property var _missionMapItems: [] ///< List of known vehicle map items
Connections {
target: multiVehicleManager
onActiveVehicleAvailableChanged: updateMissionItemsConnections()
}
function updateMissionItemsConnections() {
if (multiVehicleManager.activeVehicleAvailable) {
multiVehicleManager.activeVehicle.missionItemsChanged.connect(updateMissionItems)
} else {
// Previously active vehicle is about to go away, disconnect signals
if (multiVehicleManager.activeVehicle) {
multiVehicleManager.activeVehicle.missionItemsChanged.disconnect(updateMissionItems)
}
}
}
function addMissionItem(missionItem, index) {
if (!showMissionItems) {
console.warn("Shouldn't be called with showMissionItems=false")
return
}
if (!missionItem.hasCoordinate) {
// Item has no map position associated with it
return
}
var qmlItemTemplate = "MissionMapItem { " +
"coordinate: _missionItems[%1].coordinate; " +
"index: %2" +
"}"
var i = _missionItems.length
qmlItemTemplate = qmlItemTemplate.replace("%1", i)
qmlItemTemplate = qmlItemTemplate.replace("%2", index + 1)
_missionItems.push(missionItem)
var mapItem = Qt.createQmlObject (qmlItemTemplate, map)
_missionMapItems.push(mapItem)
mapItem.z = map.z + 1
map.addMapItem(mapItem)
}
function removeMissionItem(missionItem) {
if (!showMissionItems) {
console.warn("Shouldn't be called with showMissionItems=false")
return
}
for (var i=0; i<_missionItems.length; i++) {
if (_missionItems[i] == missionItem) {
// Qml has an annoying habit of not destroying remove Qml item until it hits the main loop.
// Because of that we need to leave the the mission item references even though we have
// removed the items, otherwise we'll get references to undefined errors until we hit the main
// loop again.
//_missionItems[i] = undefined
map.removeMapItem(_missionMapItems[i])
_missionMapItems[i] = undefined
break
}
}
}
function updateMissionItems() {
if (!showMissionItems) {
return
}
var vehicle = multiVehicleManager.activeVehicle
if (!vehicle) {
return
}
// Remove previous items
for (var i=0; i<_missionItems.length; i++) {
removeMissionItem(_missionItems[i])
}
_missionMapItems = []
// Add new items
for (var i=0; i<vehicle.missionItems.length; i++) {
addMissionItem(vehicle.missionItems[i], i)
}
}
Plugin { Plugin {
id: mapPlugin id: mapPlugin
name: "QGroundControl" name: "QGroundControl"
...@@ -345,6 +160,29 @@ Item { ...@@ -345,6 +160,29 @@ Item {
gesture.flickDeceleration: 3000 gesture.flickDeceleration: 3000
gesture.enabled: root.interactive gesture.enabled: root.interactive
// Add the vehicles to the map
MapItemView {
model: showVehicles ? multiVehicleManager.vehicles : 0
delegate:
VehicleMapItem {
coordinate: object.coordinate
heading: object.heading
isSatellite: root.isSatelliteMap
}
}
// Add the mission items to the map
MapItemView {
model: showMissionItems ? (multiVehicleManager.activeVehicle ? multiVehicleManager.activeVehicle.missionItems : 0) : 0
delegate:
MissionMapItem {
missionItem: object
}
}
/* /*
onWidthChanged: { onWidthChanged: {
scaleTimer.restart() scaleTimer.restart()
...@@ -399,32 +237,25 @@ Item { ...@@ -399,32 +237,25 @@ Item {
} }
// Mission item list // Mission item list
ScrollView { ListView {
id: missionItemScroll id: missionItemSummaryList
anchors.margins: ScreenTools.defaultFontPixelWidth anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.left: parent.left anchors.left: parent.left
anchors.right: controlWidgets.left anchors.right: controlWidgets.left
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
height: missionItemRow.height + _scrollBarHeightAdjust height: ScreenTools.defaultFontPixelHeight * 7
verticalScrollBarPolicy: Qt.ScrollBarAlwaysOff spacing: ScreenTools.defaultFontPixelWidth / 2
opacity: 0.75 opacity: 0.75
orientation: ListView.Horizontal
property bool _scrollBarShown: missionItemRow.width > missionItemScroll.width model: multiVehicleManager.activeVehicle ? multiVehicleManager.activeVehicle.missionItems : 0
property real _scrollBarHeightAdjust: _scrollBarShown ? (scrollBarHeight.height - scrollBarHeight.viewport.height) + 5 : 0
property real _maxItemHeight: 0
Row {
id: missionItemRow delegate:
spacing: ScreenTools.defaultFontPixelWidth MissionItemSummary {
opacity: 0.75
Repeater { missionItem: object
model: multiVehicleManager.activeVehicle ? multiVehicleManager.activeVehicle.missionItems : 0
MissionItemSummary {
opacity: 0.75
missionItem: modelData
}
} }
}
} }
// This is used to determine the height of a horizontal scroll bar // This is used to determine the height of a horizontal scroll bar
......
...@@ -26,16 +26,18 @@ import QtLocation 5.3 ...@@ -26,16 +26,18 @@ import QtLocation 5.3
import QGroundControl.ScreenTools 1.0 import QGroundControl.ScreenTools 1.0
import QGroundControl.Controls 1.0 import QGroundControl.Controls 1.0
import QGroundControl.Vehicle 1.0
/// Marker for displaying a mission item on the map /// Marker for displaying a mission item on the map
MapQuickItem { MapQuickItem {
property int index property var missionItem ///< Mission Item object
anchorPoint.x: sourceItem.width / 2 anchorPoint.x: sourceItem.width / 2
anchorPoint.y: sourceItem.height / 2 anchorPoint.y: sourceItem.height / 2
coordinate: missionItem.coordinate
sourceItem: sourceItem:
MissionItemIndexLabel { MissionItemIndexLabel {
missionItemIndex: index missionItemIndex: missionItem.id
} }
} }
...@@ -21,4 +21,4 @@ QGCWaypointEditor 1.0 QGCWaypointEditor.qml ...@@ -21,4 +21,4 @@ QGCWaypointEditor 1.0 QGCWaypointEditor.qml
# MapQuickItems # MapQuickItems
VehicleMapItem 1.0 VehicleMapItem.qml VehicleMapItem 1.0 VehicleMapItem.qml
MissioMapItem 1.0 MissionMapItem.qml MissionMapItem 1.0 MissionMapItem.qml
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
class MissionItem : public QObject class MissionItem : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
MissionItem( MissionItem(
QObject *parent = 0, QObject *parent = 0,
...@@ -251,6 +252,4 @@ private: ...@@ -251,6 +252,4 @@ private:
QString _oneDecimalString(double value); QString _oneDecimalString(double value);
}; };
QML_DECLARE_TYPE(MissionItem)
#endif #endif
...@@ -84,6 +84,7 @@ G_END_DECLS ...@@ -84,6 +84,7 @@ G_END_DECLS
#include "Vehicle.h" #include "Vehicle.h"
#include "MavlinkQmlSingleton.h" #include "MavlinkQmlSingleton.h"
#include "JoystickManager.h" #include "JoystickManager.h"
#include "QmlObjectListModel.h"
#ifndef __ios__ #ifndef __ios__
#include "SerialLink.h" #include "SerialLink.h"
...@@ -328,11 +329,13 @@ void QGCApplication::_initCommon(void) ...@@ -328,11 +329,13 @@ void QGCApplication::_initCommon(void)
qmlRegisterType<QGCPalette>("QGroundControl.Palette", 1, 0, "QGCPalette"); qmlRegisterType<QGCPalette>("QGroundControl.Palette", 1, 0, "QGCPalette");
qmlRegisterUncreatableType<AutoPilotPlugin>("QGroundControl.AutoPilotPlugin", 1, 0, "AutoPilotPlugin", "Can only reference, cannot create"); qmlRegisterUncreatableType<AutoPilotPlugin> ("QGroundControl.AutoPilotPlugin", 1, 0, "AutoPilotPlugin", "Can only reference, cannot create");
qmlRegisterUncreatableType<VehicleComponent>("QGroundControl.AutoPilotPlugin", 1, 0, "VehicleComponent", "Can only reference, cannot create"); qmlRegisterUncreatableType<VehicleComponent> ("QGroundControl.AutoPilotPlugin", 1, 0, "VehicleComponent", "Can only reference, cannot create");
qmlRegisterUncreatableType<Vehicle>("QGroundControl.Vehicle", 1, 0, "Vehicle", "Can only reference, cannot create"); qmlRegisterUncreatableType<Vehicle> ("QGroundControl.Vehicle", 1, 0, "Vehicle", "Can only reference, cannot create");
qmlRegisterUncreatableType<JoystickManager> ("QGroundControl.JoystickManager", 1, 0, "JoystickManager", "Reference only"); qmlRegisterUncreatableType<MissionItem> ("QGroundControl.Vehicle", 1, 0, "MissionItem", "Can only reference, cannot create");
qmlRegisterUncreatableType<Joystick> ("QGroundControl.JoystickManager", 1, 0, "Joystick", "Reference only"); qmlRegisterUncreatableType<JoystickManager> ("QGroundControl.JoystickManager", 1, 0, "JoystickManager", "Reference only");
qmlRegisterUncreatableType<Joystick> ("QGroundControl.JoystickManager", 1, 0, "Joystick", "Reference only");
qmlRegisterUncreatableType<QmlObjectListModel> ("QGroundControl", 1, 0, "QmlObjectListModel", "Reference only");
qmlRegisterType<ViewWidgetController> ("QGroundControl.Controllers", 1, 0, "ViewWidgetController"); qmlRegisterType<ViewWidgetController> ("QGroundControl.Controllers", 1, 0, "ViewWidgetController");
qmlRegisterType<ParameterEditorController> ("QGroundControl.Controllers", 1, 0, "ParameterEditorController"); qmlRegisterType<ParameterEditorController> ("QGroundControl.Controllers", 1, 0, "ParameterEditorController");
...@@ -353,8 +356,6 @@ void QGCApplication::_initCommon(void) ...@@ -353,8 +356,6 @@ void QGCApplication::_initCommon(void)
qmlRegisterSingletonType<ScreenToolsController> ("QGroundControl.ScreenToolsController", 1, 0, "ScreenToolsController", screenToolsControllerSingletonFactory); qmlRegisterSingletonType<ScreenToolsController> ("QGroundControl.ScreenToolsController", 1, 0, "ScreenToolsController", screenToolsControllerSingletonFactory);
qmlRegisterSingletonType<MavlinkQmlSingleton> ("QGroundControl.Mavlink", 1, 0, "Mavlink", mavlinkQmlSingletonFactory); qmlRegisterSingletonType<MavlinkQmlSingleton> ("QGroundControl.Mavlink", 1, 0, "Mavlink", mavlinkQmlSingletonFactory);
//-- Register MissionItem Interface
qmlRegisterInterface<MissionItem>("MissionItem");
// Show user an upgrade message if the settings version has been bumped up // Show user an upgrade message if the settings version has been bumped up
bool settingsUpgraded = false; bool settingsUpgraded = false;
if (settings.contains(_settingsVersionKey)) { if (settings.contains(_settingsVersionKey)) {
......
...@@ -2,7 +2,8 @@ import QtQuick 2.2 ...@@ -2,7 +2,8 @@ import QtQuick 2.2
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2 import QtQuick.Controls.Styles 1.2
import QGroundControl.ScreenTools 1.0 import QGroundControl.ScreenTools 1.0
import QGroundControl.Vehicle 1.0
/// Mission item summary display control /// Mission item summary display control
Rectangle { Rectangle {
...@@ -18,7 +19,7 @@ Rectangle { ...@@ -18,7 +19,7 @@ Rectangle {
MissionItemIndexLabel { MissionItemIndexLabel {
anchors.top: parent.top anchors.top: parent.top
anchors.right: parent.right anchors.right: parent.right
missionItemIndex: missionItem.id + 1 missionItemIndex: missionItem.id
} }
Column { Column {
......
/*=====================================================================
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/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "QmlObjectListModel.h"
#include <QDebug>
const int QmlObjectListModel::ObjectRole = Qt::UserRole;
QmlObjectListModel::QmlObjectListModel(QObject* parent)
: QAbstractListModel(parent)
{
}
QmlObjectListModel::~QmlObjectListModel()
{
}
int QmlObjectListModel::rowCount(const QModelIndex& parent) const
{
Q_UNUSED(parent);
return _objectList.count();
}
QVariant QmlObjectListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()) {
return QVariant();
}
if (index.row() >= _objectList.count()) {
return QVariant();
}
if (role == ObjectRole) {
return QVariant::fromValue(_objectList[index.row()]);
} else {
return QVariant();
}
}
QHash<int, QByteArray> QmlObjectListModel::roleNames(void) const
{
QHash<int, QByteArray> hash;
hash[ObjectRole] = "object";
return hash;
}
bool QmlObjectListModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if (index.isValid() && role == ObjectRole) {
_objectList.replace(index.row(), value.value<QObject*>());
emit dataChanged(index, index);
return true;
}
return false;
}
bool QmlObjectListModel::insertRows(int position, int rows, const QModelIndex& parent)
{
Q_UNUSED(parent);
beginInsertRows(QModelIndex(), position, position + rows - 1);
endInsertRows();
emit countChanged(count());
return true;
}
bool QmlObjectListModel::removeRows(int position, int rows, const QModelIndex& parent)
{
Q_UNUSED(parent);
beginRemoveRows(QModelIndex(), position, position + rows - 1);
for (int row=0; row<rows; row++) {
_objectList.removeAt(position);
}
endRemoveRows();
emit countChanged(count());
return true;
}
QObject*& QmlObjectListModel::operator[](int index)
{
return _objectList[index];
}
void QmlObjectListModel::clear(void)
{
while (rowCount()) {
removeRows(0, 1);
}
}
void QmlObjectListModel::removeAt(int i)
{
removeRows(i, 1);
}
void QmlObjectListModel::append(QObject* object)
{
_objectList += object;
insertRows(_objectList.count() - 1, 1);
}
int QmlObjectListModel::count(void)
{
return rowCount();
}
QObject* QmlObjectListModel::get(int index)
{
return _objectList[index];
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef QmlObjectListModel_H
#define QmlObjectListModel_H
#include <QAbstractListModel>
class QmlObjectListModel : public QAbstractListModel
{
Q_OBJECT
public:
QmlObjectListModel(QObject* parent = NULL);
~QmlObjectListModel();
Q_INVOKABLE QObject* get(int index);
Q_PROPERTY(int count READ count NOTIFY countChanged)
int count(void);
void append(QObject* object);
void clear(void);
void removeAt(int i);
QObject*& operator[](int i);
// Overrides from QAbstractListModel
virtual int rowCount(const QModelIndex & parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
virtual QHash<int, QByteArray> roleNames(void) const;
virtual bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex());
virtual bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex());
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
signals:
void countChanged(int count);
private:
QList<QObject*> _objectList;
static const int ObjectRole;
};
#endif
...@@ -49,7 +49,7 @@ MultiVehicleManager::~MultiVehicleManager() ...@@ -49,7 +49,7 @@ MultiVehicleManager::~MultiVehicleManager()
bool MultiVehicleManager::notifyHeartbeatInfo(LinkInterface* link, int vehicleId, mavlink_heartbeat_t& heartbeat) bool MultiVehicleManager::notifyHeartbeatInfo(LinkInterface* link, int vehicleId, mavlink_heartbeat_t& heartbeat)
{ {
if (!_vehicleMap.contains(vehicleId) && !_ignoreVehicleIds.contains(vehicleId)) { if (!getVehicleById(vehicleId) && !_ignoreVehicleIds.contains(vehicleId)) {
if (vehicleId == MAVLinkProtocol::instance()->getSystemId()) { if (vehicleId == MAVLinkProtocol::instance()->getSystemId()) {
qgcApp()->showToolBarMessage(QString("Warning: A vehicle is using the same system id as QGroundControl: %1").arg(vehicleId)); qgcApp()->showToolBarMessage(QString("Warning: A vehicle is using the same system id as QGroundControl: %1").arg(vehicleId));
} }
...@@ -74,7 +74,7 @@ bool MultiVehicleManager::notifyHeartbeatInfo(LinkInterface* link, int vehicleId ...@@ -74,7 +74,7 @@ bool MultiVehicleManager::notifyHeartbeatInfo(LinkInterface* link, int vehicleId
connect(vehicle, &Vehicle::allLinksDisconnected, this, &MultiVehicleManager::_deleteVehiclePhase1); connect(vehicle, &Vehicle::allLinksDisconnected, this, &MultiVehicleManager::_deleteVehiclePhase1);
connect(vehicle->autopilotPlugin(), &AutoPilotPlugin::pluginReadyChanged, this, &MultiVehicleManager::_autopilotPluginReadyChanged); connect(vehicle->autopilotPlugin(), &AutoPilotPlugin::pluginReadyChanged, this, &MultiVehicleManager::_autopilotPluginReadyChanged);
_vehicleMap[vehicleId] = vehicle; _vehicles.append(vehicle);
emit vehicleAdded(vehicle); emit vehicleAdded(vehicle);
...@@ -91,10 +91,10 @@ void MultiVehicleManager::_deleteVehiclePhase1(Vehicle* vehicle) ...@@ -91,10 +91,10 @@ void MultiVehicleManager::_deleteVehiclePhase1(Vehicle* vehicle)
_vehicleBeingDeleted = vehicle; _vehicleBeingDeleted = vehicle;
// Remove from map // Remove from map
bool found; bool found = false;
foreach(int id, _vehicleMap.keys()) { for (int i=0; i<_vehicles.count(); i++) {
if (_vehicleMap[id] == _vehicleBeingDeleted) { if (_vehicles[i] == _vehicleBeingDeleted) {
_vehicleMap.remove(id); _vehicles.removeAt(i);
found = true; found = true;
break; break;
} }
...@@ -128,8 +128,8 @@ void MultiVehicleManager::_deleteVehiclePhase2 (void) ...@@ -128,8 +128,8 @@ void MultiVehicleManager::_deleteVehiclePhase2 (void)
/// 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 (_vehicleMap.count()) { if (_vehicles.count()) {
newActiveVehicle = _vehicleMap.first(); newActiveVehicle = qobject_cast<Vehicle*>(_vehicles[0]);
} }
_activeVehicle = newActiveVehicle; _activeVehicle = newActiveVehicle;
...@@ -205,8 +205,8 @@ void MultiVehicleManager::_autopilotPluginReadyChanged(bool pluginReady) ...@@ -205,8 +205,8 @@ void MultiVehicleManager::_autopilotPluginReadyChanged(bool pluginReady)
void MultiVehicleManager::setHomePositionForAllVehicles(double lat, double lon, double alt) void MultiVehicleManager::setHomePositionForAllVehicles(double lat, double lon, double alt)
{ {
foreach (Vehicle* vehicle, _vehicleMap) { for (int i=0; i< _vehicles.count(); i++) {
vehicle->uas()->setHomePosition(lat, lon, alt); qobject_cast<Vehicle*>(_vehicles[i])->uas()->setHomePosition(lat, lon, alt);
} }
} }
...@@ -222,28 +222,6 @@ UASWaypointManager* MultiVehicleManager::activeWaypointManager(void) ...@@ -222,28 +222,6 @@ UASWaypointManager* MultiVehicleManager::activeWaypointManager(void)
return _offlineWaypointManager; return _offlineWaypointManager;
} }
QList<Vehicle*> MultiVehicleManager::vehicles(void)
{
QList<Vehicle*> list;
foreach (Vehicle* vehicle, _vehicleMap) {
list += vehicle;
}
return list;
}
QVariantList MultiVehicleManager::vehiclesAsVariants(void)
{
QVariantList list;
foreach (Vehicle* vehicle, _vehicleMap) {
list += QVariant::fromValue(vehicle);
}
return list;
}
void MultiVehicleManager::saveSetting(const QString &name, const QString& value) void MultiVehicleManager::saveSetting(const QString &name, const QString& value)
{ {
QSettings settings; QSettings settings;
...@@ -255,3 +233,26 @@ QString MultiVehicleManager::loadSetting(const QString &name, const QString& def ...@@ -255,3 +233,26 @@ QString MultiVehicleManager::loadSetting(const QString &name, const QString& def
QSettings settings; QSettings settings;
return settings.value(name, defaultValue).toString(); return settings.value(name, defaultValue).toString();
} }
Vehicle* MultiVehicleManager::getVehicleById(int vehicleId)
{
for (int i=0; i< _vehicles.count(); i++) {
Vehicle* vehicle = qobject_cast<Vehicle*>(_vehicles[i]);
if (vehicle->id() == vehicleId) {
return vehicle;
}
}
return NULL;
}
QList<Vehicle*> MultiVehicleManager::vehicles(void)
{
QList<Vehicle*> list;
for (int i=0; i< _vehicles.count(); i++) {
list += qobject_cast<Vehicle*>(_vehicles[i]);
}
return list;
}
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "Vehicle.h" #include "Vehicle.h"
#include "QGCMAVLink.h" #include "QGCMAVLink.h"
#include "UASWaypointManager.h" #include "UASWaypointManager.h"
#include "QmlObjectListModel.h"
class MultiVehicleManager : public QGCSingleton class MultiVehicleManager : public QGCSingleton
{ {
...@@ -42,16 +43,12 @@ public: ...@@ -42,16 +43,12 @@ public:
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(QVariantList vehicles READ vehiclesAsVariants CONSTANT) Q_PROPERTY(QmlObjectListModel* vehicles READ vehiclesModel CONSTANT)
// Property accessors // Methods
bool activeVehicleAvailable(void) { return _activeVehicleAvailable; }
bool parameterReadyVehicleAvailable(void) { return _parameterReadyVehicleAvailable; }
Vehicle* activeVehicle(void) { return _activeVehicle; }
void setActiveVehicle(Vehicle* vehicle);
/// 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.
...@@ -61,17 +58,27 @@ public: ...@@ -61,17 +58,27 @@ public:
/// @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);
Vehicle* getVehicleById(int vehicleId) { return _vehicleMap[vehicleId]; } Vehicle* getVehicleById(int vehicleId);
void setHomePositionForAllVehicles(double lat, double lon, double alt); void setHomePositionForAllVehicles(double lat, double lon, double alt);
UAS* activeUas(void) { return _activeVehicle ? _activeVehicle->uas() : NULL; } UAS* activeUas(void) { return _activeVehicle ? _activeVehicle->uas() : NULL; }
QList<Vehicle*> vehicles(void);
QVariantList vehiclesAsVariants(void);
UASWaypointManager* activeWaypointManager(void); UASWaypointManager* activeWaypointManager(void);
QList<Vehicle*> vehicles(void);
// Property accessors
bool activeVehicleAvailable(void) { return _activeVehicleAvailable; }
bool parameterReadyVehicleAvailable(void) { return _parameterReadyVehicleAvailable; }
Vehicle* activeVehicle(void) { return _activeVehicle; }
void setActiveVehicle(Vehicle* vehicle);
QmlObjectListModel* vehiclesModel(void) { return &_vehicles; }
signals: signals:
void vehicleAdded(Vehicle* vehicle); void vehicleAdded(Vehicle* vehicle);
void vehicleRemoved(Vehicle* vehicle); void vehicleRemoved(Vehicle* vehicle);
...@@ -103,7 +110,7 @@ private: ...@@ -103,7 +110,7 @@ private:
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
QMap<int, Vehicle*> _vehicleMap; ///< Map of vehicles keyed by id QmlObjectListModel _vehicles;
UASWaypointManager* _offlineWaypointManager; UASWaypointManager* _offlineWaypointManager;
}; };
......
...@@ -148,6 +148,8 @@ Vehicle::Vehicle(LinkInterface* link, int vehicleId, MAV_AUTOPILOT firmwareType) ...@@ -148,6 +148,8 @@ Vehicle::Vehicle(LinkInterface* link, int vehicleId, MAV_AUTOPILOT firmwareType)
_setSystemType(_mav, _mav->getSystemType()); _setSystemType(_mav, _mav->getSystemType());
_updateArmingState(_mav->isArmed()); _updateArmingState(_mav->isArmed());
_waypointViewOnlyListChanged();
_loadSettings(); _loadSettings();
} }
...@@ -721,21 +723,14 @@ void Vehicle::_updateWaypointViewOnly(int, MissionItem* /*wp*/) ...@@ -721,21 +723,14 @@ void Vehicle::_updateWaypointViewOnly(int, MissionItem* /*wp*/)
void Vehicle::_waypointViewOnlyListChanged() void Vehicle::_waypointViewOnlyListChanged()
{ {
if(_wpm) { if(_wpm) {
const QList<MissionItem*> &waypoints = _wpm->getWaypointViewOnlyList(); const QList<MissionItem*>& newMisionItems = _wpm->getWaypointViewOnlyList();
_waypoints.clear(); _missionItems.clear();
for(int i = 0; i < waypoints.count(); i++) { qCDebug(VehicleLog) << QString("Loading %1 mission items").arg(newMisionItems.count());
MissionItem* wp = waypoints[i]; for(int i = 0; i < newMisionItems.count(); i++) {
_waypoints.append(new MissionItem(*wp)); MissionItem* itemToCopy = newMisionItems[i];
MissionItem* item = new MissionItem(*itemToCopy);
_missionItems.append(item);
} }
emit missionItemsChanged();
/*
if(_longitude == DEFAULT_LON && _latitude == DEFAULT_LAT && _waypoints.length()) {
_longitude = _waypoints[0]->getLongitude();
_latitude = _waypoints[0]->getLatitude();
emit longitudeChanged();
emit latitudeChanged();
}
*/
} }
} }
...@@ -929,3 +924,8 @@ void Vehicle::setActive(bool active) ...@@ -929,3 +924,8 @@ void Vehicle::setActive(bool active)
_startJoystick(_active); _startJoystick(_active);
} }
QmlObjectListModel* Vehicle::missionItemsModel(void)
{
return &_missionItems;
}
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "LinkInterface.h" #include "LinkInterface.h"
#include "QGCMAVLink.h" #include "QGCMAVLink.h"
#include "MissionItem.h" #include "MissionItem.h"
#include "QmlObjectListModel.h"
class UAS; class UAS;
class UASInterface; class UASInterface;
...@@ -92,8 +93,8 @@ public: ...@@ -92,8 +93,8 @@ public:
Q_PROPERTY(uint16_t currentWaypoint READ currentWaypoint NOTIFY currentWaypointChanged) Q_PROPERTY(uint16_t currentWaypoint READ currentWaypoint NOTIFY currentWaypointChanged)
Q_PROPERTY(unsigned int heartbeatTimeout READ heartbeatTimeout NOTIFY heartbeatTimeoutChanged) Q_PROPERTY(unsigned int heartbeatTimeout READ heartbeatTimeout NOTIFY heartbeatTimeoutChanged)
//-- MissionItem management Q_PROPERTY(QmlObjectListModel* missionItems READ missionItemsModel CONSTANT)
Q_PROPERTY(QQmlListProperty<MissionItem> missionItems READ missionItems NOTIFY missionItemsChanged) QmlObjectListModel* missionItemsModel(void);
/// Returns the number of buttons which are reserved for firmware use in the MANUAL_CONTROL mavlink /// 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. /// message. For example PX4 Flight Stack reserves the first 8 buttons to simulate rc switches.
...@@ -202,8 +203,6 @@ public: ...@@ -202,8 +203,6 @@ public:
uint16_t currentWaypoint () { return _currentWaypoint; } uint16_t currentWaypoint () { return _currentWaypoint; }
unsigned int heartbeatTimeout () { return _currentHeartbeatTimeout; } unsigned int heartbeatTimeout () { return _currentHeartbeatTimeout; }
QQmlListProperty<MissionItem> missionItems() {return QQmlListProperty<MissionItem>(this, _waypoints); }
public slots: public slots:
void setLatitude(double latitude); void setLatitude(double latitude);
void setLongitude(double longitude); void setLongitude(double longitude);
...@@ -247,7 +246,6 @@ signals: ...@@ -247,7 +246,6 @@ signals:
void satelliteLockChanged (); void satelliteLockChanged ();
void waypointDistanceChanged(); void waypointDistanceChanged();
void currentWaypointChanged (); void currentWaypointChanged ();
void missionItemsChanged ();
private slots: private slots:
void _mavlinkMessageReceived(LinkInterface* link, mavlink_message_t message); void _mavlinkMessageReceived(LinkInterface* link, mavlink_message_t message);
...@@ -352,7 +350,8 @@ private: ...@@ -352,7 +350,8 @@ private:
int _satelliteLock; int _satelliteLock;
UASWaypointManager* _wpm; UASWaypointManager* _wpm;
int _updateCount; int _updateCount;
QList<MissionItem*>_waypoints;
QmlObjectListModel _missionItems;
static const char* _settingsGroup; static const char* _settingsGroup;
static const char* _joystickModeSettingsKey; static const char* _joystickModeSettingsKey;
......
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