Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
182726e2
Commit
182726e2
authored
Sep 25, 2015
by
Don Gagne
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1888 from DonLakeFlyer/MissionLoadSave
Support load/save
parents
dd0bdb5d
63080c1e
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
200 additions
and
9 deletions
+200
-9
MissionEditor.cc
src/MissionEditor/MissionEditor.cc
+101
-1
MissionEditor.h
src/MissionEditor/MissionEditor.h
+7
-1
MissionEditor.qml
src/MissionEditor/MissionEditor.qml
+29
-3
MissionItem.cc
src/MissionItem.cc
+39
-1
MissionItem.h
src/MissionItem.h
+6
-0
MissionManager.cc
src/MissionManager/MissionManager.cc
+6
-0
MissionManager.h
src/MissionManager/MissionManager.h
+12
-3
No files found.
src/MissionEditor/MissionEditor.cc
View file @
182726e2
...
...
@@ -25,6 +25,7 @@ This file is part of the QGROUNDCONTROL project
#include "ScreenToolsController.h"
#include "MultiVehicleManager.h"
#include "MissionManager.h"
#include "QGCFileDialog.h"
#include <QQmlContext>
#include <QQmlEngine>
...
...
@@ -35,6 +36,7 @@ const char* MissionEditor::_settingsGroup = "MissionEditor";
MissionEditor
::
MissionEditor
(
QWidget
*
parent
)
:
QGCQmlWidgetHolder
(
parent
)
,
_missionItems
(
NULL
)
,
_canEdit
(
true
)
{
// Get rid of layout default margins
QLayout
*
pl
=
layout
();
...
...
@@ -66,10 +68,14 @@ void MissionEditor::_newMissionItemsAvailable(void)
_missionItems
->
deleteLater
();
}
_missionItems
=
MultiVehicleManager
::
instance
()
->
activeVehicle
()
->
missionManager
()
->
copyMissionItems
();
MissionManager
*
missionManager
=
MultiVehicleManager
::
instance
()
->
activeVehicle
()
->
missionManager
();
_canEdit
=
missionManager
->
canEdit
();
_missionItems
=
missionManager
->
copyMissionItems
();
_reSequence
();
emit
missionItemsChanged
();
emit
canEditChanged
(
_canEdit
);
}
void
MissionEditor
::
getMissionItems
(
void
)
...
...
@@ -77,6 +83,8 @@ void MissionEditor::getMissionItems(void)
Vehicle
*
activeVehicle
=
MultiVehicleManager
::
instance
()
->
activeVehicle
();
if
(
activeVehicle
)
{
MissionManager
*
missionManager
=
activeVehicle
->
missionManager
();
connect
(
missionManager
,
&
MissionManager
::
newMissionItemsAvailable
,
this
,
&
MissionEditor
::
_newMissionItemsAvailable
);
activeVehicle
->
missionManager
()
->
requestMissionItems
();
}
}
...
...
@@ -92,6 +100,10 @@ void MissionEditor::setMissionItems(void)
int
MissionEditor
::
addMissionItem
(
QGeoCoordinate
coordinate
)
{
if
(
!
_canEdit
)
{
qWarning
()
<<
"addMissionItem called with _canEdit == false"
;
}
MissionItem
*
newItem
=
new
MissionItem
(
this
,
_missionItems
->
count
(),
coordinate
);
if
(
_missionItems
->
count
()
==
0
)
{
newItem
->
setCommand
(
MavlinkQmlSingleton
::
MAV_CMD_NAV_TAKEOFF
);
...
...
@@ -111,12 +123,22 @@ void MissionEditor::_reSequence(void)
void
MissionEditor
::
removeMissionItem
(
int
index
)
{
if
(
!
_canEdit
)
{
qWarning
()
<<
"addMissionItem called with _canEdit == false"
;
return
;
}
_missionItems
->
removeAt
(
index
);
_reSequence
();
}
void
MissionEditor
::
moveUp
(
int
index
)
{
if
(
!
_canEdit
)
{
qWarning
()
<<
"addMissionItem called with _canEdit == false"
;
return
;
}
if
(
_missionItems
->
count
()
<
2
||
index
<=
0
||
index
>=
_missionItems
->
count
())
{
return
;
}
...
...
@@ -135,6 +157,11 @@ void MissionEditor::moveUp(int index)
void
MissionEditor
::
moveDown
(
int
index
)
{
if
(
!
_canEdit
)
{
qWarning
()
<<
"addMissionItem called with _canEdit == false"
;
return
;
}
if
(
_missionItems
->
count
()
<
2
||
index
>=
_missionItems
->
count
()
-
1
)
{
return
;
}
...
...
@@ -150,3 +177,76 @@ void MissionEditor::moveDown(int index)
_reSequence
();
}
void
MissionEditor
::
loadMissionFromFile
(
void
)
{
QString
errorString
;
QString
filename
=
QGCFileDialog
::
getOpenFileName
(
NULL
,
"Select Mission File to load"
);
if
(
filename
.
isEmpty
())
{
return
;
}
_missionItems
->
clear
();
_canEdit
=
true
;
QFile
file
(
filename
);
if
(
!
file
.
open
(
QIODevice
::
ReadOnly
|
QIODevice
::
Text
))
{
errorString
=
file
.
errorString
();
}
else
{
QTextStream
in
(
&
file
);
const
QStringList
&
version
=
in
.
readLine
().
split
(
" "
);
if
(
!
(
version
.
size
()
==
3
&&
version
[
0
]
==
"QGC"
&&
version
[
1
]
==
"WPL"
&&
version
[
2
]
==
"120"
))
{
errorString
=
"The mission file is not compatible with the current version of QGroundControl."
;
}
else
{
while
(
!
in
.
atEnd
())
{
MissionItem
*
item
=
new
MissionItem
();
if
(
item
->
load
(
in
))
{
_missionItems
->
append
(
item
);
if
(
!
item
->
canEdit
())
{
_canEdit
=
false
;
}
}
else
{
errorString
=
"The mission file is corrupted."
;
break
;
}
}
}
}
if
(
!
errorString
.
isEmpty
())
{
_missionItems
->
clear
();
}
emit
canEditChanged
(
_canEdit
);
}
void
MissionEditor
::
saveMissionToFile
(
void
)
{
QString
errorString
;
QString
filename
=
QGCFileDialog
::
getSaveFileName
(
NULL
,
"Select file to save mission to"
);
if
(
filename
.
isEmpty
())
{
return
;
}
QFile
file
(
filename
);
if
(
!
file
.
open
(
QIODevice
::
WriteOnly
|
QIODevice
::
Text
))
{
errorString
=
file
.
errorString
();
}
else
{
QTextStream
out
(
&
file
);
out
<<
"QGC WPL 120
\r\n
"
;
// Version string
for
(
int
i
=
0
;
i
<
_missionItems
->
count
();
i
++
)
{
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
i
))
->
save
(
out
);
}
}
}
src/MissionEditor/MissionEditor.h
View file @
182726e2
...
...
@@ -35,11 +35,14 @@ public:
MissionEditor
(
QWidget
*
parent
=
NULL
);
~
MissionEditor
();
Q_PROPERTY
(
QmlObjectListModel
*
missionItems
READ
missionItemsModel
NOTIFY
missionItemsChanged
)
Q_PROPERTY
(
QmlObjectListModel
*
missionItems
READ
missionItemsModel
NOTIFY
missionItemsChanged
)
Q_PROPERTY
(
bool
canEdit
READ
canEdit
NOTIFY
canEditChanged
)
Q_INVOKABLE
int
addMissionItem
(
QGeoCoordinate
coordinate
);
Q_INVOKABLE
void
getMissionItems
(
void
);
Q_INVOKABLE
void
setMissionItems
(
void
);
Q_INVOKABLE
void
loadMissionFromFile
(
void
);
Q_INVOKABLE
void
saveMissionToFile
(
void
);
Q_INVOKABLE
void
removeMissionItem
(
int
index
);
Q_INVOKABLE
void
moveUp
(
int
index
);
Q_INVOKABLE
void
moveDown
(
int
index
);
...
...
@@ -47,9 +50,11 @@ public:
// Property accessors
QmlObjectListModel
*
missionItemsModel
(
void
)
{
return
_missionItems
;
}
bool
canEdit
(
void
)
{
return
_canEdit
;
}
signals:
void
missionItemsChanged
(
void
);
void
canEditChanged
(
bool
canEdit
);
private
slots
:
void
_newMissionItemsAvailable
();
...
...
@@ -59,6 +64,7 @@ private:
private:
QmlObjectListModel
*
_missionItems
;
bool
_canEdit
;
///< true: UI can edit these items, false: can't edit, can only send to vehicle or save
static
const
char
*
_settingsGroup
;
};
...
...
src/MissionEditor/MissionEditor.qml
View file @
182726e2
...
...
@@ -40,8 +40,8 @@ QGCView {
readonly
property
real
_defaultLatitude
:
37.803784
readonly
property
real
_defaultLongitude
:
-
122.462276
readonly
property
int
_decimalPlaces
:
7
readonly
property
real
_horizontalMargin
:
ScreenTools
.
defaultFontPixelWidth
/
2
readonly
property
real
_verticalMargin
:
ScreenTools
.
defaultFontPixelHeight
/
2
readonly
property
real
_horizontalMargin
:
ScreenTools
.
defaultFontPixelWidth
/
2
readonly
property
real
_verticalMargin
:
ScreenTools
.
defaultFontPixelHeight
/
2
readonly
property
var
_activeVehicle
:
multiVehicleManager
.
activeVehicle
property
var
_missionItems
:
controller
.
missionItems
...
...
@@ -153,6 +153,20 @@ QGCView {
onTriggered
:
controller
.
setMissionItems
()
}
MenuSeparator
{
}
MenuItem
{
text
:
"
Load mission from file...
"
onTriggered
:
controller
.
loadMissionFromFile
()
}
MenuItem
{
text
:
"
Save mission to file...
"
onTriggered
:
controller
.
saveMissionToFile
()
}
}
}
...
...
@@ -166,7 +180,7 @@ QGCView {
anchors.bottom
:
parent
.
bottom
spacing
:
_verticalMargin
orientation
:
ListView
.
Vertical
model
:
controller
.
missionItems
model
:
controller
.
canEdit
?
controller
.
missionItems
:
0
property
real
_maxItemHeight
:
0
...
...
@@ -201,6 +215,18 @@ QGCView {
wrapMode
:
Text
.
WordWrap
text
:
"
Click in the map to add Mission Items
"
}
QGCLabel
{
anchors.topMargin
:
_verticalMargin
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
anchors.top
:
toolsButton
.
bottom
anchors.bottom
:
parent
.
bottom
visible
:
!
controller
.
canEdit
wrapMode
:
Text
.
WordWrap
text
:
"
The set of mission items you have loaded cannot be edited by QGroundControl.
"
+
"
You will only be able to save these to a file, or send them to a vehicle.
"
}
}
// Item
}
// Rectangle - mission item list
}
// Item - split view container
...
...
src/MissionItem.cc
View file @
182726e2
...
...
@@ -34,6 +34,7 @@ This file is part of the QGROUNDCONTROL project
#include "MissionItem.h"
QGC_LOGGING_CATEGORY
(
MissionItemLog
,
"MissionItemLog"
)
QDebug
operator
<<
(
QDebug
dbg
,
const
MissionItem
&
missionItem
)
{
...
...
@@ -313,12 +314,20 @@ void MissionItem::setAction(int /*MAV_CMD*/ action)
if
(
_command
!=
action
)
{
_command
=
(
MavlinkQmlSingleton
::
Qml_MAV_CMD
)
action
;
// F
lick
defaults according to WP type
// F
ix
defaults according to WP type
if
(
_command
==
MavlinkQmlSingleton
::
MAV_CMD_NAV_TAKEOFF
)
{
// We default to 15 degrees minimum takeoff pitch
setParam1
(
15.0
);
}
if
(
specifiesCoordinate
())
{
if
(
_frame
!=
MAV_FRAME_GLOBAL
&&
_frame
!=
MAV_FRAME_GLOBAL_RELATIVE_ALT
)
{
setFrame
(
MAV_FRAME_GLOBAL_RELATIVE_ALT
);
}
}
else
{
setFrame
(
MAV_FRAME_MISSION
);
}
emit
changed
(
this
);
emit
commandNameChanged
(
commandName
());
...
...
@@ -758,3 +767,32 @@ void MissionItem::setCoordinate(const QGeoCoordinate& coordinate)
setLongitude
(
coordinate
.
longitude
());
setAltitude
(
coordinate
.
altitude
());
}
bool
MissionItem
::
canEdit
(
void
)
{
bool
found
=
false
;
for
(
int
i
=
0
;
i
<
_cMavCmd2Name
;
i
++
)
{
if
(
_rgMavCmd2Name
[
i
].
command
==
(
MAV_CMD
)
_command
)
{
found
=
true
;
break
;
}
}
if
(
found
)
{
if
(
!
_autocontinue
)
{
qCDebug
(
MissionItemLog
)
<<
"canEdit false due to _autocontinue != true"
;
return
false
;
}
if
(
_frame
!=
MAV_FRAME_GLOBAL
&&
_frame
!=
MAV_FRAME_GLOBAL_RELATIVE_ALT
&&
_frame
!=
MAV_FRAME_MISSION
)
{
qCDebug
(
MissionItemLog
)
<<
"canEdit false due unsupported frame type:"
<<
_frame
;
return
false
;
}
return
true
;
}
else
{
qCDebug
(
MissionItemLog
)
<<
"canEdit false due unsupported command:"
<<
_command
;
return
false
;
}
}
src/MissionItem.h
View file @
182726e2
...
...
@@ -35,6 +35,9 @@
#include "MavlinkQmlSingleton.h"
#include "QmlObjectListModel.h"
#include "Fact.h"
#include "QGCLoggingCategory.h"
Q_DECLARE_LOGGING_CATEGORY
(
MissionItemLog
)
class
MissionItem
:
public
QObject
{
...
...
@@ -104,6 +107,9 @@ public:
void
setYawDegrees
(
double
yaw
);
// C++ only methods
/// Returns true if this item can be edited in the ui
bool
canEdit
(
void
);
double
latitude
(
void
)
const
{
return
_latitudeFact
->
value
().
toDouble
();
}
double
longitude
(
void
)
const
{
return
_longitudeFact
->
value
().
toDouble
();
}
...
...
src/MissionManager/MissionManager.cc
View file @
182726e2
...
...
@@ -34,6 +34,7 @@ MissionManager::MissionManager(Vehicle* vehicle)
:
QThread
()
,
_vehicle
(
vehicle
)
,
_cMissionItems
(
0
)
,
_canEdit
(
true
)
,
_ackTimeoutTimer
(
NULL
)
,
_retryAck
(
AckNone
)
{
...
...
@@ -231,6 +232,11 @@ void MissionManager::_handleMissionItem(const mavlink_message_t& message)
missionItem
.
command
);
_missionItems
.
append
(
item
);
if
(
!
item
->
canEdit
())
{
_canEdit
=
false
;
emit
canEditChanged
(
false
);
}
int
nextSequenceNumber
=
missionItem
.
seq
+
1
;
if
(
nextSequenceNumber
==
_cMissionItems
)
{
_sendTransactionComplete
();
...
...
src/MissionManager/MissionManager.h
View file @
182726e2
...
...
@@ -47,13 +47,17 @@ public:
MissionManager
(
Vehicle
*
vehicle
);
~
MissionManager
();
Q_PROPERTY
(
bool
inProgress
READ
inProgress
CONSTANT
)
Q_PROPERTY
(
QmlObjectListModel
*
missionItems
READ
missionItems
CONSTANT
)
Q_PROPERTY
(
bool
inProgress
READ
inProgress
CONSTANT
)
Q_PROPERTY
(
QmlObjectListModel
*
missionItems
READ
missionItems
CONSTANT
)
Q_PROPERTY
(
bool
canEdit
READ
canEdit
NOTIFY
canEditChanged
)
// Property accessors
bool
inProgress
(
void
)
{
return
_retryAck
!=
AckNone
;
}
QmlObjectListModel
*
missionItems
(
void
)
{
return
&
_missionItems
;
}
bool
canEdit
(
void
)
{
return
_canEdit
;
}
// C++ methods
void
requestMissionItems
(
void
);
...
...
@@ -63,9 +67,13 @@ public:
/// Returns a copy of the current set of mission items. Caller is responsible for
/// freeing returned object.
QmlObjectListModel
*
copyMissionItems
(
void
);
signals:
// Public signals
void
canEditChanged
(
bool
canEdit
);
void
newMissionItemsAvailable
(
void
);
// Internal signals
void
_requestMissionItemsOnThread
(
void
);
void
_writeMissionItemsOnThread
(
void
);
...
...
@@ -100,6 +108,7 @@ private:
Vehicle
*
_vehicle
;
int
_cMissionItems
;
///< Mission items on vehicle
bool
_canEdit
;
///< true: Mission items are editable in the ui
QTimer
*
_ackTimeoutTimer
;
AckType_t
_retryAck
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment