Commit 982e4d06 authored by Don Gagne's avatar Don Gagne

Merge pull request #2104 from DonLakeFlyer/MissionDrag

Mission drag visuals
parents a5597700 d8fb65d6
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
<file alias="ZoomMinus.svg">src/FlightMap/Images/ZoomMinus.svg</file> <file alias="ZoomMinus.svg">src/FlightMap/Images/ZoomMinus.svg</file>
<!-- Map Buttons --> <!-- Map Buttons -->
<file alias="ArrowHead.svg">src/FlightMap/Images/ArrowHead.svg</file>
<file alias="Help.svg">src/FlightMap/Images/Help.svg</file> <file alias="Help.svg">src/FlightMap/Images/Help.svg</file>
<file alias="HelpBlack.svg">src/FlightMap/Images/HelpBlack.svg</file> <file alias="HelpBlack.svg">src/FlightMap/Images/HelpBlack.svg</file>
<file alias="MapAddMission.svg">src/FlightMap/Images/MapAddMission.svg</file> <file alias="MapAddMission.svg">src/FlightMap/Images/MapAddMission.svg</file>
......
This diff is collapsed.
...@@ -29,6 +29,8 @@ This file is part of the QGROUNDCONTROL project ...@@ -29,6 +29,8 @@ This file is part of the QGROUNDCONTROL project
#include "QGCMessageBox.h" #include "QGCMessageBox.h"
#include "FirmwarePlugin.h" #include "FirmwarePlugin.h"
QGC_LOGGING_CATEGORY(MissionControllerLog, "MissionControllerLog")
const char* MissionController::_settingsGroup = "MissionController"; const char* MissionController::_settingsGroup = "MissionController";
MissionController::MissionController(QObject *parent) MissionController::MissionController(QObject *parent)
...@@ -39,7 +41,7 @@ MissionController::MissionController(QObject *parent) ...@@ -39,7 +41,7 @@ MissionController::MissionController(QObject *parent)
, _activeVehicle(NULL) , _activeVehicle(NULL)
, _liveHomePositionAvailable(false) , _liveHomePositionAvailable(false)
, _autoSync(false) , _autoSync(false)
, _firstMissionItemSync(false) , _firstItemsFromVehicle(false)
, _missionItemsRequested(false) , _missionItemsRequested(false)
, _queuedSend(false) , _queuedSend(false)
{ {
...@@ -48,49 +50,74 @@ MissionController::MissionController(QObject *parent) ...@@ -48,49 +50,74 @@ MissionController::MissionController(QObject *parent)
MissionController::~MissionController() MissionController::~MissionController()
{ {
// Start with empty list
_canEdit = true;
_missionItems = new QmlObjectListModel(this);
_initAllMissionItems();
} }
void MissionController::start(bool editMode) void MissionController::start(bool editMode)
{ {
qCDebug(MissionControllerLog) << "start editMode" << editMode;
_editMode = editMode; _editMode = editMode;
MultiVehicleManager* multiVehicleMgr = MultiVehicleManager::instance(); MultiVehicleManager* multiVehicleMgr = MultiVehicleManager::instance();
connect(multiVehicleMgr, &MultiVehicleManager::activeVehicleChanged, this, &MissionController::_activeVehicleChanged); connect(multiVehicleMgr, &MultiVehicleManager::activeVehicleChanged, this, &MissionController::_activeVehicleChanged);
Vehicle* activeVehicle = multiVehicleMgr->activeVehicle(); _setupMissionItems(true /* fromVehicle */, true /* force */);
if (activeVehicle) { }
_activeVehicleChanged(activeVehicle);
} else { void MissionController::_newMissionItemsAvailableFromVehicle(void)
_missionItemsRequested = true; {
_newMissionItemsAvailable(); qCDebug(MissionControllerLog) << "_newMissionItemsAvailableFromVehicle";
}
_setupMissionItems(true /* fromVehicle */, false /* force */);
} }
void MissionController::_newMissionItemsAvailable(void) /// @param fromVehicle true: load items from vehicle
/// @param force true: disregard any flags which may prevent load
void MissionController::_setupMissionItems(bool fromVehicle, bool force)
{ {
if (_editMode) { qCDebug(MissionControllerLog) << "_setupMissionItems fromVehicle:force:_editMode:_firstItemsFromVehicle" << fromVehicle << force << _editMode << _firstItemsFromVehicle;
if (_firstMissionItemSync) {
// This is the first time the vehicle is seeing items. We have to be careful of transitioning from offline MissionManager* missionManager = NULL;
// to online. if (_activeVehicle) {
missionManager = _activeVehicle->missionManager();
_firstMissionItemSync = false; } else {
if (_missionItems && _missionItems->count() > 1) { qCDebug(MissionControllerLog) << "running offline";
QGCMessageBox::StandardButton button = QGCMessageBox::warning("Mission Editing", }
"The vehicle has sent a new set of Mission Items. "
"Do you want to discard your current set of unsaved items and use the ones from the vehicle instead?", if (!force) {
QGCMessageBox::Yes | QGCMessageBox::No, if (_editMode && fromVehicle) {
QGCMessageBox::No); if (_firstItemsFromVehicle) {
if (button == QGCMessageBox::No) { if (missionManager) {
if (missionManager->inProgress()) {
// Still in progress of retrieving items from vehicle, leave current set alone and wait for
// mission manager to finish
qCDebug(MissionControllerLog) << "disregarding due to MissionManager in progress";
return;
} else {
// We have the first set of items from the vehicle. If we haven't already started creating a
// new mission, switch to the items from the vehicle
_firstItemsFromVehicle = false;
if (_missionItems->count() != 1) {
qCDebug(MissionControllerLog) << "disregarding due to existing items";
return; return;
} }
} }
}
} else if (!_missionItemsRequested) { } else if (!_missionItemsRequested) {
// We didn't specifically ask for new mission items. Disregard the new set since it is // We didn't specifically ask for new mission items. Disregard the new set since it is
// the most likely the set we just sent to the vehicle. // the most likely the set we just sent to the vehicle.
qCDebug(MissionControllerLog) << "disregarding due to unrequested notification";
return; return;
} }
} }
}
qCDebug(MissionControllerLog) << "fell through to main setup";
_missionItemsRequested = false; _missionItemsRequested = false;
...@@ -99,17 +126,14 @@ void MissionController::_newMissionItemsAvailable(void) ...@@ -99,17 +126,14 @@ void MissionController::_newMissionItemsAvailable(void)
_missionItems->deleteLater(); _missionItems->deleteLater();
} }
MissionManager* missionManager = NULL; if (!missionManager || !fromVehicle || missionManager->inProgress()) {
if (_activeVehicle) {
missionManager = _activeVehicle->missionManager();
}
if (!missionManager || missionManager->inProgress()) {
_canEdit = true; _canEdit = true;
_missionItems = new QmlObjectListModel(this); _missionItems = new QmlObjectListModel(this);
qCDebug(MissionControllerLog) << "creating empty set";
} else { } else {
_canEdit = missionManager->canEdit(); _canEdit = missionManager->canEdit();
_missionItems = missionManager->copyMissionItems(); _missionItems = missionManager->copyMissionItems();
qCDebug(MissionControllerLog) << "loading from vehicle count"<< _missionItems->count();
} }
_initAllMissionItems(); _initAllMissionItems();
...@@ -121,8 +145,6 @@ void MissionController::getMissionItems(void) ...@@ -121,8 +145,6 @@ void MissionController::getMissionItems(void)
if (activeVehicle) { if (activeVehicle) {
_missionItemsRequested = true; _missionItemsRequested = true;
MissionManager* missionManager = activeVehicle->missionManager();
connect(missionManager, &MissionManager::newMissionItemsAvailable, this, &MissionController::_newMissionItemsAvailable);
activeVehicle->missionManager()->requestMissionItems(); activeVehicle->missionManager()->requestMissionItems();
} }
} }
...@@ -406,15 +428,19 @@ void MissionController::_itemCommandChanged(MavlinkQmlSingleton::Qml_MAV_CMD com ...@@ -406,15 +428,19 @@ void MissionController::_itemCommandChanged(MavlinkQmlSingleton::Qml_MAV_CMD com
void MissionController::_activeVehicleChanged(Vehicle* activeVehicle) void MissionController::_activeVehicleChanged(Vehicle* activeVehicle)
{ {
qCDebug(MissionControllerLog) << "_activeVehicleChanged activeVehicle" << activeVehicle;
if (_activeVehicle) { if (_activeVehicle) {
MissionManager* missionManager = _activeVehicle->missionManager(); MissionManager* missionManager = _activeVehicle->missionManager();
disconnect(missionManager, &MissionManager::newMissionItemsAvailable, this, &MissionController::_newMissionItemsAvailable); disconnect(missionManager, &MissionManager::newMissionItemsAvailable, this, &MissionController::_newMissionItemsAvailableFromVehicle);
disconnect(missionManager, &MissionManager::inProgressChanged, this, &MissionController::_inProgressChanged); disconnect(missionManager, &MissionManager::inProgressChanged, this, &MissionController::_inProgressChanged);
disconnect(_activeVehicle, &Vehicle::homePositionAvailableChanged, this, &MissionController::_activeVehicleHomePositionAvailableChanged); disconnect(_activeVehicle, &Vehicle::homePositionAvailableChanged, this, &MissionController::_activeVehicleHomePositionAvailableChanged);
disconnect(_activeVehicle, &Vehicle::homePositionChanged, this, &MissionController::_activeVehicleHomePositionChanged); disconnect(_activeVehicle, &Vehicle::homePositionChanged, this, &MissionController::_activeVehicleHomePositionChanged);
_activeVehicle = NULL; _activeVehicle = NULL;
_newMissionItemsAvailable();
// When the active vehicle goes away we toss the editor items
_setupMissionItems(false /* fromVehicle */, true /* force */);
_activeVehicleHomePositionAvailableChanged(false); _activeVehicleHomePositionAvailableChanged(false);
} }
...@@ -423,21 +449,13 @@ void MissionController::_activeVehicleChanged(Vehicle* activeVehicle) ...@@ -423,21 +449,13 @@ void MissionController::_activeVehicleChanged(Vehicle* activeVehicle)
if (_activeVehicle) { if (_activeVehicle) {
MissionManager* missionManager = activeVehicle->missionManager(); MissionManager* missionManager = activeVehicle->missionManager();
connect(missionManager, &MissionManager::newMissionItemsAvailable, this, &MissionController::_newMissionItemsAvailable); connect(missionManager, &MissionManager::newMissionItemsAvailable, this, &MissionController::_newMissionItemsAvailableFromVehicle);
connect(missionManager, &MissionManager::inProgressChanged, this, &MissionController::_inProgressChanged); connect(missionManager, &MissionManager::inProgressChanged, this, &MissionController::_inProgressChanged);
connect(_activeVehicle, &Vehicle::homePositionAvailableChanged, this, &MissionController::_activeVehicleHomePositionAvailableChanged); connect(_activeVehicle, &Vehicle::homePositionAvailableChanged, this, &MissionController::_activeVehicleHomePositionAvailableChanged);
connect(_activeVehicle, &Vehicle::homePositionChanged, this, &MissionController::_activeVehicleHomePositionChanged); connect(_activeVehicle, &Vehicle::homePositionChanged, this, &MissionController::_activeVehicleHomePositionChanged);
if (missionManager->inProgress()) { _firstItemsFromVehicle = true;
// Vehicle is still in process of requesting mission items _setupMissionItems(true /* fromVehicle */, false /* force */);
_firstMissionItemSync = true;
} else {
// Vehicle already has mission items
_firstMissionItemSync = false;
}
_missionItemsRequested = true;
_newMissionItemsAvailable();
_activeVehicleHomePositionChanged(_activeVehicle->homePosition()); _activeVehicleHomePositionChanged(_activeVehicle->homePosition());
_activeVehicleHomePositionAvailableChanged(_activeVehicle->homePositionAvailable()); _activeVehicleHomePositionAvailableChanged(_activeVehicle->homePositionAvailable());
......
...@@ -28,6 +28,9 @@ This file is part of the QGROUNDCONTROL project ...@@ -28,6 +28,9 @@ This file is part of the QGROUNDCONTROL project
#include "QmlObjectListModel.h" #include "QmlObjectListModel.h"
#include "Vehicle.h" #include "Vehicle.h"
#include "QGCLoggingCategory.h"
Q_DECLARE_LOGGING_CATEGORY(MissionControllerLog)
class MissionController : public QObject class MissionController : public QObject
{ {
...@@ -72,7 +75,7 @@ signals: ...@@ -72,7 +75,7 @@ signals:
void autoSyncChanged(bool autoSync); void autoSyncChanged(bool autoSync);
private slots: private slots:
void _newMissionItemsAvailable(); void _newMissionItemsAvailableFromVehicle();
void _itemCoordinateChanged(const QGeoCoordinate& coordinate); void _itemCoordinateChanged(const QGeoCoordinate& coordinate);
void _itemCommandChanged(MavlinkQmlSingleton::Qml_MAV_CMD command); void _itemCommandChanged(MavlinkQmlSingleton::Qml_MAV_CMD command);
void _activeVehicleChanged(Vehicle* activeVehicle); void _activeVehicleChanged(Vehicle* activeVehicle);
...@@ -91,6 +94,7 @@ private: ...@@ -91,6 +94,7 @@ private:
void _initMissionItem(MissionItem* item); void _initMissionItem(MissionItem* item);
void _deinitMissionItem(MissionItem* item); void _deinitMissionItem(MissionItem* item);
void _autoSyncSend(void); void _autoSyncSend(void);
void _setupMissionItems(bool fromVehicle, bool force);
private: private:
bool _editMode; bool _editMode;
...@@ -101,7 +105,7 @@ private: ...@@ -101,7 +105,7 @@ private:
bool _liveHomePositionAvailable; bool _liveHomePositionAvailable;
QGeoCoordinate _liveHomePosition; QGeoCoordinate _liveHomePosition;
bool _autoSync; bool _autoSync;
bool _firstMissionItemSync; bool _firstItemsFromVehicle;
bool _missionItemsRequested; bool _missionItemsRequested;
bool _queuedSend; bool _queuedSend;
......
...@@ -47,8 +47,6 @@ void MissionControllerManagerTest::cleanup(void) ...@@ -47,8 +47,6 @@ void MissionControllerManagerTest::cleanup(void)
void MissionControllerManagerTest::_initForFirmwareType(MAV_AUTOPILOT firmwareType) void MissionControllerManagerTest::_initForFirmwareType(MAV_AUTOPILOT firmwareType)
{ {
UnitTest::init();
LinkManager* linkMgr = LinkManager::instance(); LinkManager* linkMgr = LinkManager::instance();
Q_CHECK_PTR(linkMgr); Q_CHECK_PTR(linkMgr);
......
...@@ -36,12 +36,15 @@ MissionControllerTest::MissionControllerTest(void) ...@@ -36,12 +36,15 @@ MissionControllerTest::MissionControllerTest(void)
void MissionControllerTest::cleanup(void) void MissionControllerTest::cleanup(void)
{ {
delete _missionController; delete _missionController;
_missionController = NULL;
MissionControllerManagerTest::cleanup(); MissionControllerManagerTest::cleanup();
} }
void MissionControllerTest::_initForFirmwareType(MAV_AUTOPILOT firmwareType) void MissionControllerTest::_initForFirmwareType(MAV_AUTOPILOT firmwareType)
{ {
bool startController = false;
MissionControllerManagerTest::_initForFirmwareType(firmwareType); MissionControllerManagerTest::_initForFirmwareType(firmwareType);
_rgSignals[missionItemsChangedSignalIndex] = SIGNAL(missionItemsChanged()); _rgSignals[missionItemsChangedSignalIndex] = SIGNAL(missionItemsChanged());
...@@ -49,17 +52,22 @@ void MissionControllerTest::_initForFirmwareType(MAV_AUTOPILOT firmwareType) ...@@ -49,17 +52,22 @@ void MissionControllerTest::_initForFirmwareType(MAV_AUTOPILOT firmwareType)
_rgSignals[liveHomePositionAvailableChangedSignalIndex] = SIGNAL(liveHomePositionAvailableChanged(bool)); _rgSignals[liveHomePositionAvailableChangedSignalIndex] = SIGNAL(liveHomePositionAvailableChanged(bool));
_rgSignals[liveHomePositionChangedSignalIndex] = SIGNAL(liveHomePositionChanged(const QGeoCoordinate&)); _rgSignals[liveHomePositionChangedSignalIndex] = SIGNAL(liveHomePositionChanged(const QGeoCoordinate&));
if (!_missionController) {
startController = true;
_missionController = new MissionController(); _missionController = new MissionController();
Q_CHECK_PTR(_missionController); Q_CHECK_PTR(_missionController);
}
_multiSpy = new MultiSignalSpy(); _multiSpy = new MultiSignalSpy();
Q_CHECK_PTR(_multiSpy); Q_CHECK_PTR(_multiSpy);
QCOMPARE(_multiSpy->init(_missionController, _rgSignals, _cSignals), true); QCOMPARE(_multiSpy->init(_missionController, _rgSignals, _cSignals), true);
if (startController) {
_missionController->start(false /* editMode */); _missionController->start(false /* editMode */);
}
// All signals should some through on start // All signals should some through on start
QCOMPARE(_multiSpy->checkOnlySignalByMask(missionItemsChangedSignalMask | waypointLinesChangedSignalMask | liveHomePositionAvailableChangedSignalMask | liveHomePositionChangedSignalMask), true); QCOMPARE(_multiSpy->checkOnlySignalsByMask(missionItemsChangedSignalMask | waypointLinesChangedSignalMask | liveHomePositionAvailableChangedSignalMask | liveHomePositionChangedSignalMask), true);
_multiSpy->clearAllSignals(); _multiSpy->clearAllSignals();
QmlObjectListModel* missionItems = _missionController->missionItems(); QmlObjectListModel* missionItems = _missionController->missionItems();
...@@ -183,3 +191,28 @@ void MissionControllerTest::_testAddWayppointPX4(void) ...@@ -183,3 +191,28 @@ void MissionControllerTest::_testAddWayppointPX4(void)
{ {
_testAddWaypointWorker(MAV_AUTOPILOT_PX4); _testAddWaypointWorker(MAV_AUTOPILOT_PX4);
} }
void MissionControllerTest::_testOfflineToOnlineWorker(MAV_AUTOPILOT firmwareType)
{
// Start offline and add item
_missionController = new MissionController();
Q_CHECK_PTR(_missionController);
_missionController->start(true /* editMode */);
_missionController->addMissionItem(QGeoCoordinate(37.803784, -122.462276));
// Go online to empty vehicle
MissionControllerManagerTest::_initForFirmwareType(firmwareType);
// Make sure our offline mission items are still there
QCOMPARE(_missionController->missionItems()->count(), 2);
}
void MissionControllerTest::_testOfflineToOnlineAPM(void)
{
_testOfflineToOnlineWorker(MAV_AUTOPILOT_ARDUPILOTMEGA);
}
void MissionControllerTest::_testOfflineToOnlinePX4(void)
{
_testOfflineToOnlineWorker(MAV_AUTOPILOT_PX4);
}
...@@ -43,15 +43,19 @@ public: ...@@ -43,15 +43,19 @@ public:
private slots: private slots:
void cleanup(void); void cleanup(void);
void _testEmptyVehicleAPM(void); void _testOfflineToOnlineAPM(void);
void _testEmptyVehiclePX4(void); void _testOfflineToOnlinePX4(void);
void _testAddWayppointAPM(void);
void _testAddWayppointPX4(void);
private: private:
void _initForFirmwareType(MAV_AUTOPILOT firmwareType); void _initForFirmwareType(MAV_AUTOPILOT firmwareType);
void _testEmptyVehicleWorker(MAV_AUTOPILOT firmwareType); void _testEmptyVehicleWorker(MAV_AUTOPILOT firmwareType);
void _testAddWaypointWorker(MAV_AUTOPILOT firmwareType); void _testAddWaypointWorker(MAV_AUTOPILOT firmwareType);
void _testOfflineToOnlineWorker(MAV_AUTOPILOT firmwareType);
void _testEmptyVehicleAPM(void);
void _testEmptyVehiclePX4(void);
void _testAddWayppointAPM(void);
void _testAddWayppointPX4(void);
enum { enum {
missionItemsChangedSignalIndex = 0, missionItemsChangedSignalIndex = 0,
......
...@@ -91,8 +91,8 @@ Item { ...@@ -91,8 +91,8 @@ Item {
onPositionChanged: { onPositionChanged: {
tabletPosition = positionSource.position.coordinate tabletPosition = positionSource.position.coordinate
_root.latitude = tabletPosition.latitude flightView.latitude = tabletPosition.latitude
_root.longitude = tabletPosition.longitude flightView.longitude = tabletPosition.longitude
positionSource.active = false positionSource.active = false
} }
} }
......
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