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
51bfac2f
Commit
51bfac2f
authored
Feb 09, 2016
by
Don Gagne
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Planned Home Position support
Also additional major Mission usability changes
parent
6796b7a2
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
484 additions
and
382 deletions
+484
-382
FlightMap.qml
src/FlightMap/FlightMap.qml
+1
-1
MissionItemView.qml
src/FlightMap/MapItems/MissionItemView.qml
+1
-29
MissionLineView.qml
src/FlightMap/MapItems/MissionLineView.qml
+4
-0
MissionEditor.qml
src/MissionEditor/MissionEditor.qml
+23
-38
MissionItemStatus.qml
src/MissionEditor/MissionItemStatus.qml
+2
-5
MavCmdInfoCommon.json
src/MissionManager/MavCmdInfoCommon.json
+14
-4
MissionController.cc
src/MissionManager/MissionController.cc
+258
-173
MissionController.h
src/MissionManager/MissionController.h
+14
-11
MissionControllerTest.cc
src/MissionManager/MissionControllerTest.cc
+8
-49
MissionControllerTest.h
src/MissionManager/MissionControllerTest.h
+0
-6
MissionItem.cc
src/MissionManager/MissionItem.cc
+90
-30
MissionItem.h
src/MissionManager/MissionItem.h
+20
-6
MissionItemTest.cc
src/MissionManager/MissionItemTest.cc
+4
-0
MissionManagerTest.cc
src/MissionManager/MissionManagerTest.cc
+0
-1
QGCApplication.cc
src/QGCApplication.cc
+12
-9
QGCApplication.h
src/QGCApplication.h
+6
-5
MissionCommandDialog.qml
src/QmlControls/MissionCommandDialog.qml
+4
-2
MissionItemEditor.qml
src/QmlControls/MissionItemEditor.qml
+15
-5
QGroundControlQmlGlobal.h
src/QmlControls/QGroundControlQmlGlobal.h
+2
-2
Vehicle.cc
src/Vehicle/Vehicle.cc
+1
-1
SetupViewTest.cc
src/VehicleSetup/SetupViewTest.cc
+3
-4
UnitTestList.cc
src/qgcunittest/UnitTestList.cc
+2
-1
No files found.
src/FlightMap/FlightMap.qml
View file @
51bfac2f
...
...
@@ -51,7 +51,7 @@ Map {
readonly
property
real
maxZoomLevel
:
20
zoomLevel
:
18
center
:
QGroundControl
.
defaultMap
Position
center
:
QGroundControl
.
lastKnownHome
Position
gesture.flickDeceleration
:
3000
gesture.activeGestures
:
MapGestureArea
.
ZoomGesture
|
MapGestureArea
.
PanGesture
|
MapGestureArea
.
FlickGesture
...
...
src/FlightMap/MapItems/MissionItemView.qml
View file @
51bfac2f
...
...
@@ -35,41 +35,13 @@ import QGroundControl.Controls 1.0
MapItemView
{
id
:
_root
property
var
itemDragger
///< Set to item drag control if you want to support drag
delegate
:
MissionItemIndicator
{
id
:
itemIndicator
coordinate
:
object
.
coordinate
visible
:
object
.
specifiesCoordinate
&&
(
!
object
.
homePosition
||
object
.
homePositionValid
)
visible
:
object
.
specifiesCoordinate
&&
(
index
!=
0
||
object
.
showHomePosition
)
z
:
QGroundControl
.
zOrderMapItems
missionItem
:
object
onClicked
:
setCurrentItem
(
object
.
sequenceNumber
)
Connections
{
target
:
object
onIsCurrentItemChanged
:
{
if
(
isCurrentItem
)
{
if
(
_root
.
itemDragger
)
{
// Setup our drag item
if
(
object
.
sequenceNumber
!=
0
)
{
_root
.
itemDragger
.
visible
=
true
_root
.
itemDragger
.
missionItem
=
Qt
.
binding
(
function
()
{
return
object
})
_root
.
itemDragger
.
missionItemIndicator
=
Qt
.
binding
(
function
()
{
return
itemIndicator
})
}
else
{
_root
.
itemDragger
.
clearItem
()
}
}
// Zoom the map and move to the new position
_root
.
parent
.
zoomLevel
=
_root
.
parent
.
maxZoomLevel
_root
.
parent
.
latitude
=
object
.
coordinate
.
latitude
_root
.
parent
.
longitude
=
object
.
coordinate
.
longitude
}
}
}
// These are the non-coordinate child mission items attached to this item
Row
{
anchors.top
:
parent
.
top
...
...
src/FlightMap/MapItems/MissionLineView.qml
View file @
51bfac2f
...
...
@@ -30,6 +30,10 @@ import QGroundControl.Palette 1.0
/// The MissionLineView control is used to add lines between mission items
MapItemView
{
id
:
_root
property
bool
homePositionValid
:
true
///< true: show home position, false: don't show home position
delegate
:
MapPolyline
{
line.width
:
3
line.color
:
"
#be781c
"
// Hack, can't get palette to work in here
...
...
src/MissionEditor/MissionEditor.qml
View file @
51bfac2f
...
...
@@ -65,10 +65,6 @@ QGCView {
property
bool
_firstVehiclePosition
:
true
property
var
activeVehiclePosition
:
_activeVehicle
?
_activeVehicle
.
coordinate
:
QtPositioning
.
coordinate
()
property
var
liveHomePosition
:
controller
.
liveHomePosition
property
var
liveHomePositionAvailable
:
controller
.
liveHomePositionAvailable
property
var
homePosition
:
_defaultVehicleCoordinate
property
bool
_syncInProgress
:
_activeVehicle
?
_activeVehicle
.
missionManager
.
inProgress
:
false
Component.onCompleted
:
updateMapToVehiclePosition
()
...
...
@@ -112,27 +108,24 @@ QGCView {
/// Fix the map viewport to the current mission items. We don't fit the home position in this process.
function
fitViewportToMissionItems
()
{
if
(
_missionItems
.
count
<=
1
)
{
return
}
var
missionItem
=
_missionItems
.
get
(
1
)
var
missionItem
=
_missionItems
.
get
(
0
)
var
north
=
normalizeLat
(
missionItem
.
coordinate
.
latitude
)
var
south
=
north
var
east
=
normalizeLon
(
missionItem
.
coordinate
.
longitude
)
var
west
=
east
for
(
var
i
=
2
;
i
<
_missionItems
.
count
;
i
++
)
{
for
(
var
i
=
1
;
i
<
_missionItems
.
count
;
i
++
)
{
missionItem
=
_missionItems
.
get
(
i
)
var
lat
=
normalizeLat
(
missionItem
.
coordinate
.
latitude
)
var
lon
=
normalizeLon
(
missionItem
.
coordinate
.
longitude
)
if
(
missionItem
.
specifiesCoordinate
&&
!
missionItem
.
standaloneCoordinate
)
{
var
lat
=
normalizeLat
(
missionItem
.
coordinate
.
latitude
)
var
lon
=
normalizeLon
(
missionItem
.
coordinate
.
longitude
)
north
=
Math
.
max
(
north
,
lat
)
south
=
Math
.
min
(
south
,
lat
)
east
=
Math
.
max
(
east
,
lon
)
west
=
Math
.
min
(
west
,
lon
)
north
=
Math
.
max
(
north
,
lat
)
south
=
Math
.
min
(
south
,
lat
)
east
=
Math
.
max
(
east
,
lon
)
west
=
Math
.
min
(
west
,
lon
)
}
}
editorMap
.
visibleRegion
=
QtPositioning
.
rectangle
(
QtPositioning
.
coordinate
(
north
-
90.0
,
west
-
180.0
),
QtPositioning
.
coordinate
(
south
-
90.0
,
east
-
180.0
))
...
...
@@ -143,6 +136,7 @@ QGCView {
Component.onCompleted
:
{
start
(
true
/* editMode */
)
setCurrentItem
(
0
)
}
/*
...
...
@@ -241,13 +235,11 @@ QGCView {
anchors.fill
:
parent
onClicked
:
{
var
coordinate
=
editorMap
.
toCoordinate
(
Qt
.
point
(
mouse
.
x
,
mouse
.
y
))
coordinate
.
latitude
=
coordinate
.
latitude
.
toFixed
(
_decimalPlaces
)
coordinate
.
longitude
=
coordinate
.
longitude
.
toFixed
(
_decimalPlaces
)
coordinate
.
altitude
=
coordinate
.
altitude
.
toFixed
(
_decimalPlaces
)
if
(
false
/*homePositionManagerButton.checked*/
)
{
//offlineHomePosition = coordinate
}
else
if
(
addMissionItemsButton
.
checked
)
{
if
(
addMissionItemsButton
.
checked
)
{
var
coordinate
=
editorMap
.
toCoordinate
(
Qt
.
point
(
mouse
.
x
,
mouse
.
y
))
coordinate
.
latitude
=
coordinate
.
latitude
.
toFixed
(
_decimalPlaces
)
coordinate
.
longitude
=
coordinate
.
longitude
.
toFixed
(
_decimalPlaces
)
coordinate
.
altitude
=
coordinate
.
altitude
.
toFixed
(
_decimalPlaces
)
var
index
=
controller
.
insertMissionItem
(
coordinate
,
controller
.
missionItems
.
count
)
setCurrentItem
(
index
)
}
else
{
...
...
@@ -318,7 +310,7 @@ QGCView {
MissionItemIndicator
{
id
:
itemIndicator
coordinate
:
object
.
coordinate
visible
:
object
.
specifiesCoordinate
&&
(
!
object
.
homePosition
||
object
.
homePositionValid
)
visible
:
object
.
specifiesCoordinate
z
:
QGroundControl
.
zOrderMapItems
missionItem
:
object
...
...
@@ -329,13 +321,9 @@ QGCView {
if
(
object
.
isCurrentItem
&&
itemIndicator
.
visible
)
{
if
(
object
.
specifiesCoordinate
)
{
// Setup our drag item
if
(
object
.
sequenceNumber
!=
0
)
{
itemDragger
.
visible
=
true
itemDragger
.
missionItem
=
Qt
.
binding
(
function
()
{
return
object
})
itemDragger
.
missionItemIndicator
=
Qt
.
binding
(
function
()
{
return
itemIndicator
})
}
else
{
itemDragger
.
clearItem
()
}
}
}
}
...
...
@@ -379,7 +367,6 @@ QGCView {
anchors.bottom
:
parent
.
bottom
anchors.right
:
parent
.
right
width
:
_rightPanelWidth
visible
:
_missionItems
.
count
>
1
opacity
:
_rightPanelOpacity
z
:
QGroundControl
.
zOrderTopMost
...
...
@@ -399,13 +386,11 @@ QGCView {
property
real
_maxItemHeight
:
0
delegate
:
MissionItemEditor
{
delegate
:
MissionItemEditor
{
missionItem
:
object
width
:
parent
.
width
readOnly
:
object
.
sequenceNumber
==
0
visible
:
!
readOnly
||
object
.
homePositionValid
qgcView
:
_root
readOnly
:
false
onClicked
:
setCurrentItem
(
object
.
sequenceNumber
)
...
...
@@ -423,6 +408,8 @@ QGCView {
controller
.
insertMissionItem
(
editorMap
.
center
,
i
)
setCurrentItem
(
i
)
}
onMoveHomeToMapCenter
:
controller
.
missionItems
.
get
(
0
).
coordinate
=
editorMap
.
center
}
}
// ListView
}
// Item - Mission Item editor
...
...
@@ -485,12 +472,11 @@ QGCView {
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCButton
{
text
:
"
Home
"
enabled
:
liveHomePositionAvailable
text
:
"
Home
"
onClicked
:
{
centerMapButton
.
hideDropDown
()
editorMap
.
center
=
liveHomePosition
editorMap
.
center
=
controller
.
missionItems
.
get
(
0
).
coordinate
}
}
...
...
@@ -582,7 +568,6 @@ QGCView {
currentMissionItem
:
_currentMissionItem
missionItems
:
controller
.
missionItems
expandedWidth
:
missionItemEditor
.
x
-
(
ScreenTools
.
defaultFontPixelWidth
*
2
)
homePositionValid
:
liveHomePositionAvailable
}
}
// FlightMap
}
// Item - split view container
...
...
src/MissionEditor/MissionItemStatus.qml
View file @
51bfac2f
...
...
@@ -32,7 +32,6 @@ Rectangle {
property
var
currentMissionItem
///< Mission item to display status for
property
var
missionItems
///< List of all available mission items
property
real
expandedWidth
///< Width of control when expanded
property
bool
homePositionValid
:
false
/// true: home position in missionItems[0] is valid
width
:
_expanded
?
expandedWidth
:
_collapsedWidth
height
:
expandLabel
.
y
+
expandLabel
.
height
+
_margins
...
...
@@ -49,7 +48,7 @@ Rectangle {
property
real
_altDifference
:
_currentMissionItem
?
_currentMissionItem
.
altDifference
:
-
1
property
real
_azimuth
:
_currentMissionItem
?
_currentMissionItem
.
azimuth
:
-
1
property
real
_isHomePosition
:
_currentMissionItem
?
_currentMissionItem
.
homePosition
:
false
property
bool
_statusValid
:
_distance
!=
-
1
&&
((
_isHomePosition
&&
homePositionValid
)
||
!
_isHomePosition
)
property
bool
_statusValid
:
_distance
!=
-
1
property
string
_distanceText
:
_statusValid
?
Math
.
round
(
_distance
)
+
"
meters
"
:
""
property
string
_altText
:
_statusValid
?
Math
.
round
(
_altDifference
)
+
"
meters
"
:
""
property
string
_azimuthText
:
_statusValid
?
Math
.
round
(
_azimuth
)
:
""
...
...
@@ -115,9 +114,7 @@ Rectangle {
property
real
availableHeight
:
height
-
ScreenTools
.
smallFontPixelHeight
-
indicator
.
height
// If home position is not valid we are graphing relative based on a home alt of 0. Because of this
// we cannot graph absolute altitudes since we have no basis for comparison against the relative values.
property
bool
graphAbsolute
:
homePositionValid
property
bool
graphAbsolute
:
true
MissionItemIndexLabel
{
id
:
indicator
...
...
src/MissionManager/MavCmdInfoCommon.json
View file @
51bfac2f
...
...
@@ -6,11 +6,21 @@
"comment"
:
"MAV_CMD_NAV_LAST: Used for fake home position waypoint"
,
"id"
:
95
,
"rawName"
:
"HomeRaw"
,
"friendlyName"
:
"Home"
,
"description"
:
"Home Position"
,
"description"
:
"Home Position"
,
"friendlyName"
:
"Home Position"
,
"description"
:
"Planned home position for mission."
,
"specifiesCoordinate"
:
true
,
"friendlyEdit"
:
true
"friendlyEdit"
:
true
,
"category"
:
"Basic"
,
"param5"
:
{
"label"
:
"Latitude:"
,
"default"
:
37.803784
,
"decimalPlaces"
:
7
},
"param6"
:
{
"label"
:
"Longitude:"
,
"default"
:
-122.462276
,
"decimalPlaces"
:
7
}
},
{
"id"
:
16
,
...
...
src/MissionManager/MissionController.cc
View file @
51bfac2f
...
...
@@ -34,14 +34,18 @@ This file is part of the QGROUNDCONTROL project
QGC_LOGGING_CATEGORY
(
MissionControllerLog
,
"MissionControllerLog"
)
const
char
*
MissionController
::
_settingsGroup
=
"MissionController"
;
const
char
*
MissionController
::
_settingsGroup
=
"MissionController"
;
const
char
*
MissionController
::
_jsonVersionKey
=
"version"
;
const
char
*
MissionController
::
_jsonGroundStationKey
=
"groundStation"
;
const
char
*
MissionController
::
_jsonMavAutopilotKey
=
"MAV_AUTOPILOT"
;
const
char
*
MissionController
::
_jsonItemsKey
=
"items"
;
const
char
*
MissionController
::
_jsonPlannedHomePositionKey
=
"plannedHomePosition"
;
MissionController
::
MissionController
(
QObject
*
parent
)
:
QObject
(
parent
)
,
_editMode
(
false
)
,
_missionItems
(
NULL
)
,
_activeVehicle
(
NULL
)
,
_liveHomePositionAvailable
(
false
)
,
_autoSync
(
false
)
,
_firstItemsFromVehicle
(
false
)
,
_missionItemsRequested
(
false
)
...
...
@@ -64,76 +68,37 @@ void MissionController::start(bool editMode)
MultiVehicleManager
*
multiVehicleMgr
=
qgcApp
()
->
toolbox
()
->
multiVehicleManager
();
connect
(
multiVehicleMgr
,
&
MultiVehicleManager
::
activeVehicleChanged
,
this
,
&
MissionController
::
_activeVehicleChanged
);
_activeVehicleChanged
(
multiVehicleMgr
->
activeVehicle
());
_setupMissionItems
(
true
/* loadFromVehicle */
,
true
/* forceLoad */
);
_setupActiveVehicle
(
multiVehicleMgr
->
activeVehicle
(),
true
/* forceLoadFromVehicle */
);
// We start with an empty mission
_missionItems
=
new
QmlObjectListModel
(
this
);
_addPlannedHomePosition
(
false
/* addToCenter */
);
_initAllMissionItems
();
}
// Called when new mission items have completed downloading from Vehicle
void
MissionController
::
_newMissionItemsAvailableFromVehicle
(
void
)
{
qCDebug
(
MissionControllerLog
)
<<
"_newMissionItemsAvailableFromVehicle"
;
_setupMissionItems
(
true
/* loadFromVehicle */
,
false
/* forceLoad */
);
}
if
(
!
_editMode
||
_missionItemsRequested
||
_missionItems
->
count
()
==
1
)
{
// Fly Mode:
// - Always accepts new items fromthe vehicle so Fly view is kept up to date
// Edit Mode:
// - Either a load from vehicle was manually requested or
// - The initial automatic load from a vehicle completed and the current editor it empty
_deinitAllMissionItems
();
_missionItems
->
deleteLater
();
/// @param loadFromVehicle true: load items from vehicle
/// @param forceLoad true: disregard any flags which may prevent load
void
MissionController
::
_setupMissionItems
(
bool
loadFromVehicle
,
bool
forceLoad
)
{
qCDebug
(
MissionControllerLog
)
<<
"_setupMissionItems loadFromVehicle:forceLoad:_editMode:_firstItemsFromVehicle"
<<
loadFromVehicle
<<
forceLoad
<<
_editMode
<<
_firstItemsFromVehicle
;
_missionItems
=
_activeVehicle
->
missionManager
()
->
copyMissionItems
();
qCDebug
(
MissionControllerLog
)
<<
"loading from vehicle count"
<<
_missionItems
->
count
();
MissionManager
*
missionManager
=
NULL
;
if
(
_activeVehicle
)
{
missionManager
=
_activeVehicle
->
missionManager
();
}
else
{
qCDebug
(
MissionControllerLog
)
<<
"running offline"
;
}
if
(
!
forceLoad
)
{
if
(
_editMode
&&
loadFromVehicle
)
{
if
(
_firstItemsFromVehicle
)
{
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
;
}
}
}
}
else
if
(
!
_missionItemsRequested
)
{
// 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.
qCDebug
(
MissionControllerLog
)
<<
"disregarding due to unrequested notification"
;
return
;
}
if
(
!
_activeVehicle
->
firmwarePlugin
()
->
sendHomePositionToVehicle
()
||
_missionItems
->
count
()
==
0
)
{
_addPlannedHomePosition
(
true
/* addToCenter */
);
}
}
qCDebug
(
MissionControllerLog
)
<<
"fell through to main setup"
;
_missionItemsRequested
=
false
;
if
(
_missionItems
)
{
_deinitAllMissionItems
();
_missionItems
->
deleteLater
();
}
_missionItemsRequested
=
false
;
if
(
!
missionManager
||
!
loadFromVehicle
||
missionManager
->
inProgress
())
{
_missionItems
=
new
QmlObjectListModel
(
this
);
qCDebug
(
MissionControllerLog
)
<<
"creating empty set"
;
_initAllMissionItems
();
}
else
{
_missionItems
=
missionManager
->
copyMissionItems
();
qCDebug
(
MissionControllerLog
)
<<
"loading from vehicle count"
<<
_missionItems
->
count
();
_initAllMissionItems
();
emit
newItemsFromVehicle
();
}
...
...
@@ -192,6 +157,7 @@ void MissionController::removeMissionItem(int index)
MissionItem
*
item
=
qobject_cast
<
MissionItem
*>
(
_missionItems
->
removeAt
(
index
));
_deinitMissionItem
(
item
);
item
->
deleteLater
();
_recalcAll
();
...
...
@@ -204,26 +170,127 @@ void MissionController::removeMissionItem(int index)
MissionItem
*
item
=
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
i
));
item
->
setIsCurrentItem
(
i
==
index
);
}
_missionItems
->
setDirty
(
true
);
}
void
MissionController
::
removeAllMissionItems
(
void
)
{
if
(
_missionItems
)
{
_deinitAllMissionItems
();
_missionItems
->
deleteLater
();
while
(
_missionItems
->
count
()
!=
1
)
{
removeMissionItem
(
_missionItems
->
count
()
-
1
);
}
}
_missionItems
=
new
QmlObjectListModel
(
this
);
}
_initAllMissionItems
();
_missionItems
->
setDirty
(
true
);
#ifndef __mobile__
bool
MissionController
::
_loadJsonMissionFile
(
const
QByteArray
&
bytes
,
QString
&
errorString
)
{
QJsonParseError
jsonParseError
;
QJsonDocument
jsonDoc
(
QJsonDocument
::
fromJson
(
bytes
,
&
jsonParseError
));
if
(
jsonParseError
.
error
!=
QJsonParseError
::
NoError
)
{
errorString
=
jsonParseError
.
errorString
();
return
false
;
}
QJsonObject
json
=
jsonDoc
.
object
();
if
(
!
json
.
contains
(
_jsonVersionKey
))
{
errorString
=
QStringLiteral
(
"File is missing version key"
);
return
false
;
}
if
(
json
[
_jsonVersionKey
].
toString
()
!=
"1.0"
)
{
errorString
=
QStringLiteral
(
"QGroundControl does not support this file version"
);
return
false
;
}
if
(
json
.
contains
(
_jsonItemsKey
))
{
if
(
!
json
[
_jsonItemsKey
].
isArray
())
{
errorString
=
QStringLiteral
(
"items values must be array"
);
return
false
;
}
QJsonArray
itemArray
(
json
[
_jsonItemsKey
].
toArray
());
foreach
(
const
QJsonValue
&
itemValue
,
itemArray
)
{
if
(
!
itemValue
.
isObject
())
{
errorString
=
QStringLiteral
(
"Mission item is not an object"
);
return
false
;
}
MissionItem
*
item
=
new
MissionItem
(
_activeVehicle
,
this
);
if
(
item
->
load
(
itemValue
.
toObject
(),
errorString
))
{
_missionItems
->
append
(
item
);
}
else
{
return
false
;
}
}
}
if
(
json
.
contains
(
_jsonPlannedHomePositionKey
))
{
MissionItem
*
item
=
new
MissionItem
(
_activeVehicle
,
this
);
if
(
item
->
load
(
json
[
_jsonPlannedHomePositionKey
].
toObject
(),
errorString
))
{
_missionItems
->
insert
(
0
,
item
);
}
else
{
return
false
;
}
}
else
{
_addPlannedHomePosition
(
true
/* addToCenter */
);
}
return
true
;
}
#endif
#ifndef __mobile__
bool
MissionController
::
_loadTextMissionFile
(
QTextStream
&
stream
,
QString
&
errorString
)
{
bool
addPlannedHomePosition
=
false
;
QString
firstLine
=
stream
.
readLine
();
const
QStringList
&
version
=
firstLine
.
split
(
" "
);
bool
versionOk
=
false
;
if
(
version
.
size
()
==
3
&&
version
[
0
]
==
"QGC"
&&
version
[
1
]
==
"WPL"
)
{
if
(
version
[
2
]
==
"110"
)
{
// ArduPilot file, planned home position is already in position 0
versionOk
=
true
;
}
else
if
(
version
[
2
]
==
"120"
)
{
// Old QGC file, no planned home position
versionOk
=
true
;
addPlannedHomePosition
=
true
;
}
}
if
(
versionOk
)
{
while
(
!
stream
.
atEnd
())
{
MissionItem
*
item
=
new
MissionItem
(
_activeVehicle
,
this
);
if
(
item
->
load
(
stream
))
{
_missionItems
->
append
(
item
);
}
else
{
errorString
=
QStringLiteral
(
"The mission file is corrupted."
);
return
false
;
}
}
}
else
{
errorString
=
QStringLiteral
(
"The mission file is not compatible with this version of QGroundControl."
);
return
false
;
}
if
(
addPlannedHomePosition
||
_missionItems
->
count
()
==
0
)
{
_addPlannedHomePosition
(
true
/* addToCenter */
);
}
return
true
;
}
#endif
void
MissionController
::
loadMissionFromFile
(
void
)
{
#ifndef __mobile__
QString
errorString
;
QString
filename
=
QGCFileDialog
::
getOpenFileName
(
NULL
,
"Select Mission File to load"
);
bool
versionAPM
=
false
;
QString
filename
=
QGCFileDialog
::
getOpenFileName
(
NULL
,
"Select Mission File to load"
,
QString
(),
"Mission file (*.mission);;All Files (*.*)"
);
if
(
filename
.
isEmpty
())
{
return
;
...
...
@@ -235,53 +302,32 @@ void MissionController::loadMissionFromFile(void)
}
_missionItems
=
new
QmlObjectListModel
(
this
);
// FIXME: This needs to handle APM files which have WP 0 in them
QFile
file
(
filename
);
if
(
!
file
.
open
(
QIODevice
::
ReadOnly
|
QIODevice
::
Text
))
{
errorString
=
file
.
errorString
();
}
else
{
QTextStream
in
(
&
file
);
const
QStringList
&
version
=
in
.
readLine
().
split
(
" "
);
QByteArray
bytes
=
file
.
readAll
();
QTextStream
stream
(
&
bytes
);
bool
versionOk
=
false
;
if
(
version
.
size
()
==
3
&&
version
[
0
]
==
"QGC"
&&
version
[
1
]
==
"WPL"
)
{
if
(
version
[
2
]
==
"120"
)
{
versionOk
=
true
;
}
else
if
(
version
[
2
]
==
"110"
)
{
versionOk
=
true
;
versionAPM
=
true
;
}
}
if
(
versionOk
)
{
while
(
!
in
.
atEnd
())
{
MissionItem
*
item
=
new
MissionItem
(
_activeVehicle
,
this
);
if
(
item
->
load
(
in
))
{
_missionItems
->
append
(
item
);
}
else
{
errorString
=
"The mission file is corrupted."
;
break
;
}
}
QString
firstLine
=
stream
.
readLine
();
if
(
firstLine
.
contains
(
QRegExp
(
"QGC.*WPL"
)))
{
stream
.
seek
(
0
);
_loadTextMissionFile
(
stream
,
errorString
);
}
else
{
errorString
=
"The mission file is not compatible with this version of QGroundControl."
;
_loadJsonMissionFile
(
bytes
,
errorString
)
;
}
}
if
(
errorString
.
isEmpty
())
{
if
(
versionAPM
)
{
// Remove fake home position from APM files
_missionItems
->
removeAt
(
0
);
}
}
else
{
if
(
!
errorString
.
isEmpty
())
{
_missionItems
->
clear
();
qgcApp
()
->
showMessage
(
errorString
);
}
if
(
_missionItems
->
count
()
==
0
)
{
_addPlannedHomePosition
(
true
/* addToCenter */
);
}
_initAllMissionItems
();
#endif
}
...
...
@@ -289,31 +335,59 @@ void MissionController::loadMissionFromFile(void)
void
MissionController
::
saveMissionToFile
(
void
)
{
#ifndef __mobile__
QString
filename
=
QGCFileDialog
::
getSaveFileName
(
NULL
,
"Select file to save mission to"
);
QString
filename
=
QGCFileDialog
::
getSaveFileName
(
NULL
,
"Select file to save mission to"
,
QString
(),
"Mission file (*.mission);;All Files (*.*)"
);
if
(
filename
.
isEmpty
())
{
return
;
}
if
(
!
QFileInfo
(
filename
).
fileName
().
contains
(
"."
))
{
filename
+=
".mission"
;
}
QFile
file
(
filename
);
if
(
!
file
.
open
(
QIODevice
::
WriteOnly
|
QIODevice
::
Text
))
{
qgcApp
()
->
showMessage
(
file
.
errorString
());
}
else
{
Q
TextStream
out
(
&
file
)
;
Q
JsonObject
missionObject
;
out
<<
"QGC WPL 120
\r\n
"
;
// Version string
missionObject
[
_jsonVersionKey
]
=
"1.0"
;
missionObject
[
_jsonGroundStationKey
]
=
"QGroundControl"
;
MAV_AUTOPILOT
firmwareType
=
MAV_AUTOPILOT_GENERIC
;
if
(
_activeVehicle
)
{
firmwareType
=
_activeVehicle
->
firmwareType
();
}
else
{
// FIXME: Hack duplicated code from QGroundControlQmlGlobal. Had to do this for now since
// QGroundControlQmlGlobal is not available from C++ side.
QSettings
settings
;
firmwareType
=
(
MAV_AUTOPILOT
)
settings
.
value
(
"OfflineEditingFirmwareType"
,
MAV_AUTOPILOT_ARDUPILOTMEGA
).
toInt
();
}
missionObject
[
_jsonMavAutopilotKey
]
=
firmwareType
;
QJsonObject
homePositionObject
;
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
0
))
->
save
(
homePositionObject
);
missionObject
[
"plannedHomePosition"
]
=
homePositionObject
;
QJsonArray
itemArray
;
for
(
int
i
=
1
;
i
<
_missionItems
->
count
();
i
++
)
{
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
i
))
->
save
(
out
);
QJsonObject
itemObject
;
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
i
))
->
save
(
itemObject
);
itemArray
.
append
(
itemObject
);
}
missionObject
[
"items"
]
=
itemArray
;
QJsonDocument
saveDoc
(
missionObject
);
file
.
write
(
saveDoc
.
toJson
());
}
_missionItems
->
setDirty
(
false
);
#endif
}
void
MissionController
::
_calcPrevWaypointValues
(
bool
homePositionValid
,
double
homeAlt
,
MissionItem
*
currentItem
,
MissionItem
*
prevItem
,
double
*
azimuth
,
double
*
distance
,
double
*
altDifference
)
void
MissionController
::
_calcPrevWaypointValues
(
double
homeAlt
,
MissionItem
*
currentItem
,
MissionItem
*
prevItem
,
double
*
azimuth
,
double
*
distance
,
double
*
altDifference
)
{
QGeoCoordinate
currentCoord
=
currentItem
->
coordinate
();
QGeoCoordinate
prevCoord
=
prevItem
->
coordinate
();
...
...
@@ -321,22 +395,16 @@ void MissionController::_calcPrevWaypointValues(bool homePositionValid, double h
// Convert to fixed altitudes
qCDebug
(
MissionControllerLog
)
<<
home
PositionValid
<<
home
Alt
qCDebug
(
MissionControllerLog
)
<<
homeAlt
<<
currentItem
->
relativeAltitude
()
<<
currentItem
->
coordinate
().
altitude
()
<<
prevItem
->
relativeAltitude
()
<<
prevItem
->
coordinate
().
altitude
();
if
(
homePositionValid
)
{
distanceOk
=
true
;
if
(
currentItem
->
relativeAltitude
())
{
currentCoord
.
setAltitude
(
homeAlt
+
currentCoord
.
altitude
());
}
if
(
prevItem
->
relativeAltitude
())
{
prevCoord
.
setAltitude
(
homeAlt
+
prevCoord
.
altitude
());
}
}
else
{
if
(
prevItem
->
relativeAltitude
()
&&
currentItem
->
relativeAltitude
())
{
distanceOk
=
true
;
}
distanceOk
=
true
;
if
(
currentItem
->
relativeAltitude
())
{
currentCoord
.
setAltitude
(
homeAlt
+
currentCoord
.
altitude
());
}
if
(
prevItem
->
relativeAltitude
())
{
prevCoord
.
setAltitude
(
homeAlt
+
prevCoord
.
altitude
());
}
qCDebug
(
MissionControllerLog
)
<<
"distanceOk"
<<
distanceOk
;
...
...
@@ -357,7 +425,7 @@ void MissionController::_recalcWaypointLines(void)
MissionItem
*
lastCoordinateItem
=
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
0
));
MissionItem
*
homeItem
=
lastCoordinateItem
;
bool
firstCoordinateItem
=
true
;
bool
homePositionValid
=
homeItem
->
homePositionValid
();
bool
showHomePosition
=
homeItem
->
showHomePosition
();
double
homeAlt
=
homeItem
->
coordinate
().
altitude
();
qCDebug
(
MissionControllerLog
)
<<
"_recalcWaypointLines"
;
...
...
@@ -387,7 +455,7 @@ void MissionController::_recalcWaypointLines(void)
if
(
item
->
specifiesCoordinate
())
{
double
absoluteAltitude
=
item
->
coordinate
().
altitude
();
if
(
item
->
relativeAltitude
()
&&
homePositionValid
)
{
if
(
item
->
relativeAltitude
())
{
absoluteAltitude
+=
homePositionAltitude
;
}
minAltSeen
=
std
::
min
(
minAltSeen
,
absoluteAltitude
);
...
...
@@ -396,12 +464,12 @@ void MissionController::_recalcWaypointLines(void)
if
(
!
item
->
standaloneCoordinate
())
{
if
(
firstCoordinateItem
)
{
if
(
item
->
command
()
==
MavlinkQmlSingleton
::
MAV_CMD_NAV_TAKEOFF
)
{
// The first coordinate we hit is a takeoff command so link back to home position
if valid
if
(
homePositionValid
)
{
// The first coordinate we hit is a takeoff command so link back to home position
if
(
showHomePosition
)
{
double
azimuth
,
distance
,
altDifference
;
_waypointLines
.
append
(
new
CoordinateVector
(
homeItem
->
coordinate
(),
item
->
coordinate
()));
_calcPrevWaypointValues
(
home
PositionValid
,
home
Alt
,
item
,
homeItem
,
&
azimuth
,
&
distance
,
&
altDifference
);
_calcPrevWaypointValues
(
homeAlt
,
item
,
homeItem
,
&
azimuth
,
&
distance
,
&
altDifference
);
item
->
setAltDifference
(
altDifference
);
item
->
setAzimuth
(
azimuth
);
item
->
setDistance
(
distance
);
...
...
@@ -410,12 +478,12 @@ void MissionController::_recalcWaypointLines(void)
// First coordiante is not a takeoff command, it does not link backwards to anything
}
firstCoordinateItem
=
false
;
}
else
if
(
!
lastCoordinateItem
->
homePosition
()
||
lastCoordinateItem
->
homePositionValid
()
)
{
}
else
if
(
!
lastCoordinateItem
->
homePosition
()
||
showHomePosition
)
{
double
azimuth
,
distance
,
altDifference
;
// Subsequent coordinate items link to last coordinate item. If the last coordinate item
// is an invalid home position we skip the line
_calcPrevWaypointValues
(
home
PositionValid
,
home
Alt
,
item
,
lastCoordinateItem
,
&
azimuth
,
&
distance
,
&
altDifference
);
_calcPrevWaypointValues
(
homeAlt
,
item
,
lastCoordinateItem
,
&
azimuth
,
&
distance
,
&
altDifference
);
item
->
setAltDifference
(
altDifference
);
item
->
setAzimuth
(
azimuth
);
item
->
setDistance
(
distance
);
...
...
@@ -433,7 +501,7 @@ void MissionController::_recalcWaypointLines(void)
if
(
item
->
specifiesCoordinate
())
{
double
absoluteAltitude
=
item
->
coordinate
().
altitude
();
if
(
item
->
relativeAltitude
()
&&
homePositionValid
)
{
if
(
item
->
relativeAltitude
())
{
absoluteAltitude
+=
homePositionAltitude
;
}
if
(
altRange
==
0.0
)
{
...
...
@@ -485,36 +553,24 @@ void MissionController::_recalcAll(void)
_recalcWaypointLines
();
}
/// Initializes a new set of mission items
which may have come from the vehicle or have been loaded from a file
/// Initializes a new set of mission items
void
MissionController
::
_initAllMissionItems
(
void
)
{
MissionItem
*
homeItem
=
NULL
;
if
(
_activeVehicle
&&
_activeVehicle
->
firmwarePlugin
()
->
sendHomePositionToVehicle
()
&&
_missionItems
->
count
()
!=
0
)
{
homeItem
=
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
0
));
}
else
{
// Add the home position item to the front
homeItem
=
new
MissionItem
(
_activeVehicle
,
this
);
homeItem
->
setSequenceNumber
(
0
);
_missionItems
->
insert
(
0
,
homeItem
);
}
homeItem
=
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
0
));
homeItem
->
setHomePositionSpecialCase
(
true
);
if
(
_activeVehicle
)
{
homeItem
->
setHomePositionValid
(
_activeVehicle
->
homePositionAvailable
());
if
(
homeItem
->
homePositionValid
())
{
homeItem
->
setCoordinate
(
_activeVehicle
->
homePosition
());
}
}
else
{
homeItem
->
setHomePositionValid
(
false
);
}
homeItem
->
setShowHomePosition
(
_editMode
);
homeItem
->
setCommand
(
MAV_CMD_NAV_WAYPOINT
);
homeItem
->
setFrame
(
MAV_FRAME_GLOBAL
);
if
(
!
homeItem
->
homePositionValid
())
{
// Set a bogus home position, the important value is 0.0 Altitude
homeItem
->
setCoordinate
(
QGeoCoordinate
(
37.803784
,
-
122.462276
,
0.0
));
homeItem
->
setIsCurrentItem
(
true
);
if
(
!
_editMode
&&
_activeVehicle
&&
_activeVehicle
->
homePositionAvailable
())
{
homeItem
->
setCoordinate
(
_activeVehicle
->
homePosition
());
homeItem
->
setShowHomePosition
(
true
);
}
//qDebug() << "home item" << homeItem->homePositionValid()
<< homeItem->coordinate();
qDebug
()
<<
"home item"
<<
homeItem
->
coordinate
();
for
(
int
i
=
0
;
i
<
_missionItems
->
count
();
i
++
)
{
_initMissionItem
(
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
i
)));
...
...
@@ -585,22 +641,6 @@ void MissionController::_activeVehicleChanged(Vehicle* activeVehicle)
disconnect
(
_activeVehicle
,
&
Vehicle
::
homePositionAvailableChanged
,
this
,
&
MissionController
::
_activeVehicleHomePositionAvailableChanged
);
disconnect
(
_activeVehicle
,
&
Vehicle
::
homePositionChanged
,
this
,
&
MissionController
::
_activeVehicleHomePositionChanged
);
_activeVehicle
=
NULL
;
// When the active vehicle goes away we toss the editor items
_setupMissionItems
(
false
/* loadFromVehicle */
,
true
/* forceLoad */
);
_activeVehicleHomePositionAvailableChanged
(
false
);
}
_setupActiveVehicle
(
activeVehicle
,
false
/* forceLoadFromVehicle */
);
}
void
MissionController
::
_setupActiveVehicle
(
Vehicle
*
activeVehicle
,
bool
forceLoadFromVehicle
)
{
qCDebug
(
MissionControllerLog
)
<<
"_setupActiveVehicle activeVehicle:forceLoadFromVehicle"
<<
activeVehicle
<<
forceLoadFromVehicle
;
if
(
_activeVehicle
)
{
qCWarning
(
MissionControllerLog
)
<<
"_activeVehicle != NULL"
;
}
_activeVehicle
=
activeVehicle
;
...
...
@@ -613,8 +653,9 @@ void MissionController::_setupActiveVehicle(Vehicle* activeVehicle, bool forceLo
connect
(
_activeVehicle
,
&
Vehicle
::
homePositionAvailableChanged
,
this
,
&
MissionController
::
_activeVehicleHomePositionAvailableChanged
);
connect
(
_activeVehicle
,
&
Vehicle
::
homePositionChanged
,
this
,
&
MissionController
::
_activeVehicleHomePositionChanged
);
_firstItemsFromVehicle
=
true
;
_setupMissionItems
(
true
/* fromVehicle */
,
forceLoadFromVehicle
);
if
(
!
_editMode
)
{
removeAllMissionItems
();
}
_activeVehicleHomePositionChanged
(
_activeVehicle
->
homePosition
());
_activeVehicleHomePositionAvailableChanged
(
_activeVehicle
->
homePositionAvailable
());
...
...
@@ -623,18 +664,18 @@ void MissionController::_setupActiveVehicle(Vehicle* activeVehicle, bool forceLo
void
MissionController
::
_activeVehicleHomePositionAvailableChanged
(
bool
homePositionAvailable
)
{
_liveHomePositionAvailable
=
homePositionAvailable
;
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
0
))
->
setHomePositionValid
(
homePositionAvailable
);
emit
liveHomePositionAvailableChanged
(
_liveHomePositionAvailable
);
_recalcWaypointLines
();
if
(
!
_editMode
&&
_missionItems
)
{
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
0
))
->
setShowHomePosition
(
homePositionAvailable
);
_recalcWaypointLines
(
);
}
}
void
MissionController
::
_activeVehicleHomePositionChanged
(
const
QGeoCoordinate
&
homePosition
)
{
_liveHomePosition
=
homePosition
;
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
0
))
->
setCoordinate
(
_liveH
omePosition
);
emit
liveHomePositionChanged
(
_liveHomePosition
);
_recalcWaypointLines
();
if
(
!
_editMode
&&
_missionItems
)
{
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
0
))
->
setCoordinate
(
h
omePosition
);
_recalcWaypointLines
(
);
}
}
void
MissionController
::
setAutoSync
(
bool
autoSync
)
...
...
@@ -730,3 +771,47 @@ bool MissionController::_findLastAcceptanceRadius(double* lastAcceptanceRadius)
return
found
;
}
double
MissionController
::
_normalizeLat
(
double
lat
)
{
// Normalize latitude to range: 0 to 180, S to N
return
lat
+
90.0
;
}
double
MissionController
::
_normalizeLon
(
double
lon
)
{
// Normalize longitude to range: 0 to 360, W to E
return
lon
+
180.0
;
}
/// Add the home position item to the front of the list
void
MissionController
::
_addPlannedHomePosition
(
bool
addToCenter
)
{
MissionItem
*
homeItem
=
new
MissionItem
(
_activeVehicle
,
this
);
_missionItems
->
insert
(
0
,
homeItem
);
if
(
_missionItems
->
count
()
>
1
&&
addToCenter
)
{
MissionItem
*
item
=
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
1
));
double
north
=
_normalizeLat
(
item
->
coordinate
().
latitude
());
double
south
=
north
;
double
east
=
_normalizeLon
(
item
->
coordinate
().
longitude
());
double
west
=
east
;
for
(
int
i
=
2
;
i
<
_missionItems
->
count
();
i
++
)
{
item
=
qobject_cast
<
MissionItem
*>
(
_missionItems
->
get
(
i
));
double
lat
=
_normalizeLat
(
item
->
coordinate
().
latitude
());
double
lon
=
_normalizeLon
(
item
->
coordinate
().
longitude
());
north
=
fmax
(
north
,
lat
);
south
=
fmin
(
south
,
lat
);
east
=
fmax
(
east
,
lon
);
west
=
fmin
(
west
,
lon
);
}
homeItem
->
setCoordinate
(
QGeoCoordinate
((
south
+
((
north
-
south
)
/
2
))
-
90.0
,
(
west
+
((
east
-
west
)
/
2
))
-
180.0
,
0.0
));
}
else
{
homeItem
->
setCoordinate
(
qgcApp
()
->
lastKnownHomePosition
());
}
}
src/MissionManager/MissionController.h
View file @
51bfac2f
...
...
@@ -42,8 +42,6 @@ public:
Q_PROPERTY
(
QmlObjectListModel
*
missionItems
READ
missionItems
NOTIFY
missionItemsChanged
)
Q_PROPERTY
(
QmlObjectListModel
*
waypointLines
READ
waypointLines
NOTIFY
waypointLinesChanged
)
Q_PROPERTY
(
bool
liveHomePositionAvailable
READ
liveHomePositionAvailable
NOTIFY
liveHomePositionAvailableChanged
)
Q_PROPERTY
(
QGeoCoordinate
liveHomePosition
READ
liveHomePosition
NOTIFY
liveHomePositionChanged
)
Q_PROPERTY
(
bool
autoSync
READ
autoSync
WRITE
setAutoSync
NOTIFY
autoSyncChanged
)
Q_INVOKABLE
void
start
(
bool
editMode
);
...
...
@@ -61,16 +59,12 @@ public:
QmlObjectListModel
*
missionItems
(
void
);
QmlObjectListModel
*
waypointLines
(
void
)
{
return
&
_waypointLines
;
}
bool
liveHomePositionAvailable
(
void
)
{
return
_liveHomePositionAvailable
;
}
QGeoCoordinate
liveHomePosition
(
void
)
{
return
_liveHomePosition
;
}
bool
autoSync
(
void
)
{
return
_autoSync
;
}
void
setAutoSync
(
bool
autoSync
);
signals:
void
missionItemsChanged
(
void
);
void
waypointLinesChanged
(
void
);
void
liveHomePositionAvailableChanged
(
bool
homePositionAvailable
);
void
liveHomePositionChanged
(
const
QGeoCoordinate
&
homePosition
);
void
autoSyncChanged
(
bool
autoSync
);
void
newItemsFromVehicle
(
void
);
...
...
@@ -95,25 +89,34 @@ private:
void
_initMissionItem
(
MissionItem
*
item
);
void
_deinitMissionItem
(
MissionItem
*
item
);
void
_autoSyncSend
(
void
);
void
_setupMissionItems
(
bool
loadFromVehicle
,
bool
forceLoad
);
void
_setupActiveVehicle
(
Vehicle
*
activeVehicle
,
bool
forceLoadFromVehicle
);
void
_calcPrevWaypointValues
(
bool
homePositionValid
,
double
homeAlt
,
MissionItem
*
currentItem
,
MissionItem
*
prevItem
,
double
*
azimuth
,
double
*
distance
,
double
*
altDifference
);
void
_calcPrevWaypointValues
(
double
homeAlt
,
MissionItem
*
currentItem
,
MissionItem
*
prevItem
,
double
*
azimuth
,
double
*
distance
,
double
*
altDifference
);
bool
_findLastAltitude
(
double
*
lastAltitude
);
bool
_findLastAcceptanceRadius
(
double
*
lastAcceptanceRadius
);
void
_addPlannedHomePosition
(
bool
addToCenter
);
double
_normalizeLat
(
double
lat
);
double
_normalizeLon
(
double
lon
);
#ifndef __mobile__
bool
_loadJsonMissionFile
(
const
QByteArray
&
bytes
,
QString
&
errorString
);
bool
_loadTextMissionFile
(
QTextStream
&
stream
,
QString
&
errorString
);
#endif
private:
bool
_editMode
;
QmlObjectListModel
*
_missionItems
;
QmlObjectListModel
_waypointLines
;
Vehicle
*
_activeVehicle
;
bool
_liveHomePositionAvailable
;
QGeoCoordinate
_liveHomePosition
;
bool
_autoSync
;
bool
_firstItemsFromVehicle
;
bool
_missionItemsRequested
;
bool
_queuedSend
;
static
const
char
*
_settingsGroup
;
static
const
char
*
_settingsGroup
;
static
const
char
*
_jsonVersionKey
;
static
const
char
*
_jsonGroundStationKey
;
static
const
char
*
_jsonMavAutopilotKey
;
static
const
char
*
_jsonItemsKey
;
static
const
char
*
_jsonPlannedHomePositionKey
;
};
#endif
src/MissionManager/MissionControllerTest.cc
View file @
51bfac2f
...
...
@@ -59,14 +59,11 @@ void MissionControllerTest::_initForFirmwareType(MAV_AUTOPILOT firmwareType)
void
homePositionValidChanged
(
bool
homePostionValid
);
// MissionItem signals
_rgMissionItemSignals
[
coordinateChangedSignalIndex
]
=
SIGNAL
(
coordinateChanged
(
const
QGeoCoordinate
&
));
_rgMissionItemSignals
[
homePositionValidChangedSignalIndex
]
=
SIGNAL
(
homePositionValidChanged
(
bool
));
_rgMissionItemSignals
[
coordinateChangedSignalIndex
]
=
SIGNAL
(
coordinateChanged
(
const
QGeoCoordinate
&
));
// MissionController signals
_rgMissionControllerSignals
[
missionItemsChangedSignalIndex
]
=
SIGNAL
(
missionItemsChanged
());
_rgMissionControllerSignals
[
waypointLinesChangedSignalIndex
]
=
SIGNAL
(
waypointLinesChanged
());
_rgMissionControllerSignals
[
liveHomePositionAvailableChangedSignalIndex
]
=
SIGNAL
(
liveHomePositionAvailableChanged
(
bool
));
_rgMissionControllerSignals
[
liveHomePositionChangedSignalIndex
]
=
SIGNAL
(
liveHomePositionChanged
(
const
QGeoCoordinate
&
));
_rgMissionControllerSignals
[
missionItemsChangedSignalIndex
]
=
SIGNAL
(
missionItemsChanged
());
_rgMissionControllerSignals
[
waypointLinesChangedSignalIndex
]
=
SIGNAL
(
waypointLinesChanged
());
if
(
!
_missionController
)
{
startController
=
true
;
...
...
@@ -83,7 +80,7 @@ void MissionControllerTest::_initForFirmwareType(MAV_AUTOPILOT firmwareType)
}
// All signals should some through on start
QCOMPARE
(
_multiSpyMissionController
->
checkOnlySignalsByMask
(
missionItemsChangedSignalMask
|
waypointLinesChangedSignalMask
|
liveHomePositionAvailableChangedSignalMask
|
liveHomePositionChangedSignalMask
),
true
);
QCOMPARE
(
_multiSpyMissionController
->
checkOnlySignalsByMask
(
missionItemsChangedSignalMask
|
waypointLinesChangedSignalMask
),
true
);
_multiSpyMissionController
->
clearAllSignals
();
QmlObjectListModel
*
missionItems
=
_missionController
->
missionItems
();
...
...
@@ -96,7 +93,6 @@ void MissionControllerTest::_initForFirmwareType(MAV_AUTOPILOT firmwareType)
MissionItem
*
homeItem
=
qobject_cast
<
MissionItem
*>
(
missionItems
->
get
(
0
));
QVERIFY
(
homeItem
);
QCOMPARE
(
homeItem
->
homePosition
(),
true
);
QCOMPARE
(
homeItem
->
homePositionValid
(),
false
);
// Home should have no children
QCOMPARE
(
homeItem
->
childItems
()
->
count
(),
0
);
...
...
@@ -106,9 +102,6 @@ void MissionControllerTest::_initForFirmwareType(MAV_AUTOPILOT firmwareType)
QVERIFY
(
waypointLines
);
QCOMPARE
(
waypointLines
->
count
(),
0
);
// Should not have home position yet
QCOMPARE
(
_missionController
->
liveHomePositionAvailable
(),
false
);
// AutoSync should be off by default
QCOMPARE
(
_missionController
->
autoSync
(),
false
);
}
...
...
@@ -120,44 +113,12 @@ void MissionControllerTest::_testEmptyVehicleWorker(MAV_AUTOPILOT firmwareType)
// FYI: A significant amount of empty vehicle testing is in _initForFirmwareType since that
// sets up an empty vehicle
// APM stack doesn't support HOME_POSITION yet
bool
expectedHomePositionValid
=
firmwareType
==
MAV_AUTOPILOT_PX4
?
true
:
false
;
QmlObjectListModel
*
missionItems
=
_missionController
->
missionItems
();
QVERIFY
(
missionItems
);
MissionItem
*
homeItem
=
qobject_cast
<
MissionItem
*>
(
missionItems
->
get
(
0
));
QVERIFY
(
homeItem
);
_setupMissionItemSignals
(
homeItem
);
if
(
expectedHomePositionValid
)
{
// Wait for the home position to show up
if
(
!
_missionController
->
liveHomePositionAvailable
())
{
QVERIFY
(
_multiSpyMissionController
->
waitForSignalByIndex
(
liveHomePositionAvailableChangedSignalIndex
,
2000
));
QCOMPARE
(
_multiSpyMissionController
->
pullBoolFromSignalIndex
(
liveHomePositionAvailableChangedSignalIndex
),
true
);
}
if
(
!
homeItem
->
homePositionValid
())
{
QVERIFY
(
_multiSpyMissionItem
->
waitForSignalByIndex
(
homePositionValidChangedSignalIndex
,
2000
));
QCOMPARE
(
_multiSpyMissionItem
->
pullBoolFromSignalIndex
(
homePositionValidChangedSignalIndex
),
true
);
}
// Once the home position shows up we get a number of addititional signals
QCOMPARE
(
_multiSpyMissionController
->
checkOnlySignalsByMask
(
liveHomePositionChangedSignalMask
|
liveHomePositionAvailableChangedSignalMask
|
waypointLinesChangedSignalMask
),
true
);
QCOMPARE
(
_multiSpyMissionController
->
checkSignalByMask
(
liveHomePositionChangedSignalMask
|
liveHomePositionAvailableChangedSignalMask
),
true
);
QCOMPARE
(
_multiSpyMissionController
->
checkSignalByMask
(
waypointLinesChangedSignalMask
),
false
);
QCOMPARE
(
_multiSpyMissionItem
->
checkSignalByMask
(
homePositionValidChangedSignalMask
),
true
);
_multiSpyMissionController
->
clearAllSignals
();
_multiSpyMissionItem
->
clearAllSignals
();
}
QCOMPARE
(
homeItem
->
homePositionValid
(),
expectedHomePositionValid
);
QCOMPARE
(
_missionController
->
liveHomePositionAvailable
(),
expectedHomePositionValid
);
QCOMPARE
(
_missionController
->
liveHomePosition
().
isValid
(),
expectedHomePositionValid
);
}
void
MissionControllerTest
::
_testEmptyVehiclePX4
(
void
)
...
...
@@ -194,16 +155,14 @@ void MissionControllerTest::_testAddWaypointWorker(MAV_AUTOPILOT firmwareType)
QCOMPARE
(
homeItem
->
childItems
()
->
count
(),
firmwareType
==
MAV_AUTOPILOT_ARDUPILOTMEGA
?
1
:
0
);
QCOMPARE
(
item
->
childItems
()
->
count
(),
0
);
int
expectedLineCount
;
if
(
homeItem
->
homePositionValid
())
{
expectedLineCount
=
1
;
}
else
{
expectedLineCount
=
0
;
}
#if 0
// This needs re-work
int expectedLineCount = firmwareType == MAV_AUTOPILOT_ARDUPILOTMEGA ? 0 : 1;
QmlObjectListModel* waypointLines = _missionController->waypointLines();
QVERIFY(waypointLines);
QCOMPARE(waypointLines->count(), expectedLineCount);
#endif
}
void
MissionControllerTest
::
_testAddWayppointAPM
(
void
)
...
...
src/MissionManager/MissionControllerTest.h
View file @
51bfac2f
...
...
@@ -61,13 +61,11 @@ private:
enum
{
coordinateChangedSignalIndex
=
0
,
homePositionValidChangedSignalIndex
,
missionItemMaxSignalIndex
};
enum
{
coordinateChangedSignalMask
=
1
<<
coordinateChangedSignalIndex
,
homePositionValidChangedSignalMask
=
1
<<
homePositionValidChangedSignalIndex
,
missionItemMaxSignalMask
=
1
<<
missionItemMaxSignalIndex
,
};
...
...
@@ -76,16 +74,12 @@ private:
enum
{
missionItemsChangedSignalIndex
=
0
,
waypointLinesChangedSignalIndex
,
liveHomePositionAvailableChangedSignalIndex
,
liveHomePositionChangedSignalIndex
,
missionControllerMaxSignalIndex
};
enum
{
missionItemsChangedSignalMask
=
1
<<
missionItemsChangedSignalIndex
,
waypointLinesChangedSignalMask
=
1
<<
waypointLinesChangedSignalIndex
,
liveHomePositionAvailableChangedSignalMask
=
1
<<
liveHomePositionAvailableChangedSignalIndex
,
liveHomePositionChangedSignalMask
=
1
<<
liveHomePositionChangedSignalIndex
,
};
MultiSignalSpy
*
_multiSpyMissionController
;
...
...
src/MissionManager/MissionItem.cc
View file @
51bfac2f
...
...
@@ -26,6 +26,7 @@ This file is part of the QGROUNDCONTROL project
#include "MissionItem.h"
#include "FirmwarePluginManager.h"
#include "QGCApplication.h"
#include "JsonHelper.h"
QGC_LOGGING_CATEGORY
(
MissionItemLog
,
"MissionItemLog"
)
...
...
@@ -38,6 +39,18 @@ FactMetaData* MissionItem::_frameMetaData = NULL;
FactMetaData
*
MissionItem
::
_latitudeMetaData
=
NULL
;
FactMetaData
*
MissionItem
::
_longitudeMetaData
=
NULL
;
const
char
*
MissionItem
::
_itemType
=
"missionItem"
;
const
char
*
MissionItem
::
_jsonTypeKey
=
"type"
;
const
char
*
MissionItem
::
_jsonIdKey
=
"id"
;
const
char
*
MissionItem
::
_jsonFrameKey
=
"frame"
;
const
char
*
MissionItem
::
_jsonCommandKey
=
"command"
;
const
char
*
MissionItem
::
_jsonParam1Key
=
"param1"
;
const
char
*
MissionItem
::
_jsonParam2Key
=
"param2"
;
const
char
*
MissionItem
::
_jsonParam3Key
=
"param3"
;
const
char
*
MissionItem
::
_jsonParam4Key
=
"param4"
;
const
char
*
MissionItem
::
_jsonAutoContinueKey
=
"autoContinue"
;
const
char
*
MissionItem
::
_jsonCoordinateKey
=
"coordinate"
;
struct
EnumInfo_s
{
const
char
*
label
;
MAV_FRAME
frame
;
...
...
@@ -86,7 +99,7 @@ MissionItem::MissionItem(Vehicle* vehicle, QObject* parent)
,
_azimuth
(
0.0
)
,
_distance
(
0.0
)
,
_homePositionSpecialCase
(
false
)
,
_
homePositionValid
(
false
)
,
_
showHomePosition
(
false
)
,
_altitudeRelativeToHomeFact
(
0
,
"Altitude is relative to home"
,
FactMetaData
::
valueTypeUint32
)
,
_autoContinueFact
(
0
,
"AutoContinue"
,
FactMetaData
::
valueTypeUint32
)
,
_commandFact
(
0
,
""
,
FactMetaData
::
valueTypeUint32
)
...
...
@@ -147,7 +160,7 @@ MissionItem::MissionItem(Vehicle* vehicle,
,
_azimuth
(
0.0
)
,
_distance
(
0.0
)
,
_homePositionSpecialCase
(
false
)
,
_
homePositionValid
(
false
)
,
_
showHomePosition
(
false
)
,
_altitudeRelativeToHomeFact
(
0
,
"Altitude is relative to home"
,
FactMetaData
::
valueTypeUint32
)
,
_commandFact
(
0
,
""
,
FactMetaData
::
valueTypeUint32
)
,
_frameFact
(
0
,
""
,
FactMetaData
::
valueTypeUint32
)
...
...
@@ -205,7 +218,7 @@ MissionItem::MissionItem(const MissionItem& other, QObject* parent)
,
_azimuth
(
0.0
)
,
_distance
(
0.0
)
,
_homePositionSpecialCase
(
false
)
,
_
homePositionValid
(
false
)
,
_
showHomePosition
(
false
)
,
_altitudeRelativeToHomeFact
(
0
,
"Altitude is relative to home"
,
FactMetaData
::
valueTypeUint32
)
,
_commandFact
(
0
,
""
,
FactMetaData
::
valueTypeUint32
)
,
_frameFact
(
0
,
""
,
FactMetaData
::
valueTypeUint32
)
...
...
@@ -252,7 +265,7 @@ const MissionItem& MissionItem::operator=(const MissionItem& other)
setAzimuth
(
other
.
_azimuth
);
setDistance
(
other
.
_distance
);
setHomePositionSpecialCase
(
other
.
_homePositionSpecialCase
);
set
HomePositionValid
(
other
.
_homePositionValid
);
set
ShowHomePosition
(
other
.
_showHomePosition
);
_syncFrameToAltitudeRelativeToHome
();
...
...
@@ -360,22 +373,21 @@ MissionItem::~MissionItem()
{
}
void
MissionItem
::
save
(
Q
TextStream
&
saveStream
)
void
MissionItem
::
save
(
Q
JsonObject
&
json
)
{
// FORMAT: <INDEX> <CURRENT WP> <COORD FRAME> <COMMAND> <PARAM1> <PARAM2> <PARAM3> <PARAM4> <PARAM5/X/LONGITUDE> <PARAM6/Y/LATITUDE> <PARAM7/Z/ALTITUDE> <autoContinue> <DESCRIPTION>
// as documented here: http://qgroundcontrol.org/waypoint_protocol
saveStream
<<
sequenceNumber
()
<<
"
\t
"
<<
isCurrentItem
()
<<
"
\t
"
<<
frame
()
<<
"
\t
"
<<
command
()
<<
"
\t
"
<<
QString
(
"%1"
).
arg
(
param1
(),
0
,
'g'
,
18
)
<<
"
\t
"
<<
QString
(
"%1"
).
arg
(
param2
(),
0
,
'g'
,
18
)
<<
"
\t
"
<<
QString
(
"%1"
).
arg
(
param3
(),
0
,
'g'
,
18
)
<<
"
\t
"
<<
QString
(
"%1"
).
arg
(
param4
(),
0
,
'g'
,
18
)
<<
"
\t
"
<<
QString
(
"%1"
).
arg
(
param5
(),
0
,
'g'
,
18
)
<<
"
\t
"
<<
QString
(
"%1"
).
arg
(
param6
(),
0
,
'g'
,
18
)
<<
"
\t
"
<<
QString
(
"%1"
).
arg
(
param7
(),
0
,
'g'
,
18
)
<<
"
\t
"
<<
this
->
autoContinue
()
<<
"
\r\n
"
;
json
[
_jsonTypeKey
]
=
_itemType
;
json
[
_jsonIdKey
]
=
sequenceNumber
();
json
[
_jsonFrameKey
]
=
frame
();
json
[
_jsonCommandKey
]
=
command
();
json
[
_jsonParam1Key
]
=
param1
();
json
[
_jsonParam2Key
]
=
param2
();
json
[
_jsonParam3Key
]
=
param3
();
json
[
_jsonParam4Key
]
=
param4
();
json
[
_jsonAutoContinueKey
]
=
autoContinue
();
QJsonArray
coordinateArray
;
coordinateArray
<<
param5
()
<<
param6
()
<<
param7
();
json
[
_jsonCoordinateKey
]
=
coordinateArray
;
}
bool
MissionItem
::
load
(
QTextStream
&
loadStream
)
...
...
@@ -396,9 +408,45 @@ bool MissionItem::load(QTextStream &loadStream)
setAutoContinue
(
wpParams
[
11
].
toInt
()
==
1
?
true
:
false
);
return
true
;
}
return
false
;
}
bool
MissionItem
::
load
(
const
QJsonObject
&
json
,
QString
&
errorString
)
{
QStringList
requiredKeys
;
requiredKeys
<<
_jsonTypeKey
<<
_jsonIdKey
<<
_jsonFrameKey
<<
_jsonCommandKey
<<
_jsonParam1Key
<<
_jsonParam2Key
<<
_jsonParam3Key
<<
_jsonParam4Key
<<
_jsonAutoContinueKey
<<
_jsonCoordinateKey
;
if
(
!
JsonHelper
::
validateRequiredKeys
(
json
,
requiredKeys
,
errorString
))
{
return
false
;
}
if
(
json
[
_jsonTypeKey
]
!=
_itemType
)
{
errorString
=
QString
(
"type found: %1 must be: %2"
).
arg
(
json
[
_jsonTypeKey
].
toString
()).
arg
(
_itemType
);
return
false
;
}
QGeoCoordinate
coordinate
;
if
(
!
JsonHelper
::
toQGeoCoordinate
(
json
[
_jsonCoordinateKey
],
coordinate
,
true
/* altitudeRequired */
,
errorString
))
{
return
false
;
}
setCoordinate
(
coordinate
);
setIsCurrentItem
(
false
);
setSequenceNumber
(
json
[
_jsonIdKey
].
toInt
());
setFrame
((
MAV_FRAME
)
json
[
_jsonFrameKey
].
toInt
());
setCommand
((
MAV_CMD
)
json
[
_jsonCommandKey
].
toInt
());
setParam1
(
json
[
_jsonParam1Key
].
toDouble
());
setParam2
(
json
[
_jsonParam2Key
].
toDouble
());
setParam3
(
json
[
_jsonParam3Key
].
toDouble
());
setParam4
(
json
[
_jsonParam4Key
].
toDouble
());
setAutoContinue
(
json
[
_jsonAutoContinueKey
].
toBool
());
return
true
;
}
void
MissionItem
::
setSequenceNumber
(
int
sequenceNumber
)
{
...
...
@@ -562,7 +610,12 @@ QmlObjectListModel* MissionItem::textFieldFacts(void)
}
else
{
_clearParamMetaData
();
MAV_CMD
command
=
(
MAV_CMD
)
this
->
command
();
MAV_CMD
command
;
if
(
_homePositionSpecialCase
)
{
command
=
MAV_CMD_NAV_LAST
;
}
else
{
command
=
(
MAV_CMD
)
this
->
command
();
}
Fact
*
rgParamFacts
[
7
]
=
{
&
_param1Fact
,
&
_param2Fact
,
&
_param3Fact
,
&
_param4Fact
,
&
_param5Fact
,
&
_param6Fact
,
&
_param7Fact
};
FactMetaData
*
rgParamMetaData
[
7
]
=
{
&
_param1MetaData
,
&
_param2MetaData
,
&
_param3MetaData
,
&
_param4MetaData
,
&
_param5MetaData
,
&
_param6MetaData
,
&
_param7MetaData
};
...
...
@@ -601,7 +654,7 @@ QmlObjectListModel* MissionItem::checkboxFacts(void)
if
(
rawEdit
())
{
model
->
append
(
&
_autoContinueFact
);
}
else
if
(
specifiesCoordinate
())
{
}
else
if
(
specifiesCoordinate
()
&&
!
_homePositionSpecialCase
)
{
model
->
append
(
&
_altitudeRelativeToHomeFact
);
}
...
...
@@ -619,7 +672,12 @@ QmlObjectListModel* MissionItem::comboboxFacts(void)
Fact
*
rgParamFacts
[
7
]
=
{
&
_param1Fact
,
&
_param2Fact
,
&
_param3Fact
,
&
_param4Fact
,
&
_param5Fact
,
&
_param6Fact
,
&
_param7Fact
};
FactMetaData
*
rgParamMetaData
[
7
]
=
{
&
_param1MetaData
,
&
_param2MetaData
,
&
_param3MetaData
,
&
_param4MetaData
,
&
_param5MetaData
,
&
_param6MetaData
,
&
_param7MetaData
};
MAV_CMD
command
=
(
MAV_CMD
)
this
->
command
();
MAV_CMD
command
;
if
(
_homePositionSpecialCase
)
{
command
=
MAV_CMD_NAV_LAST
;
}
else
{
command
=
(
MAV_CMD
)
this
->
command
();
}
for
(
int
i
=
1
;
i
<=
7
;
i
++
)
{
const
QMap
<
int
,
MavCmdParamInfo
*>&
paramInfoMap
=
_missionCommands
->
getMavCmdInfo
(
command
,
_vehicle
)
->
paramInfoMap
();
...
...
@@ -663,9 +721,9 @@ bool MissionItem::friendlyEditAllowed(void) const
if
(
specifiesCoordinate
())
{
return
frame
()
==
MAV_FRAME_GLOBAL
||
frame
()
==
MAV_FRAME_GLOBAL_RELATIVE_ALT
;
}
else
{
return
frame
()
==
MAV_FRAME_MISSION
;
}
return
true
;
}
return
false
;
...
...
@@ -701,12 +759,6 @@ void MissionItem::_setDirtyFromSignal(void)
setDirty
(
true
);
}
void
MissionItem
::
setHomePositionValid
(
bool
homePositionValid
)
{
_homePositionValid
=
homePositionValid
;
emit
homePositionValidChanged
(
_homePositionValid
);
}
void
MissionItem
::
setDistance
(
double
distance
)
{
_distance
=
distance
;
...
...
@@ -808,3 +860,11 @@ QString MissionItem::category(void) const
{
return
qgcApp
()
->
toolbox
()
->
missionCommands
()
->
categoryFromCommand
(
command
());
}
void
MissionItem
::
setShowHomePosition
(
bool
showHomePosition
)
{
if
(
showHomePosition
!=
_showHomePosition
)
{
_showHomePosition
=
showHomePosition
;
emit
showHomePositionChanged
(
_showHomePosition
);
}
}
src/MissionManager/MissionItem.h
View file @
51bfac2f
...
...
@@ -28,6 +28,7 @@
#include <QString>
#include <QtQml>
#include <QTextStream>
#include <QJsonObject>
#include <QGeoCoordinate>
#include "QGCMAVLink.h"
...
...
@@ -81,13 +82,13 @@ public:
Q_PROPERTY
(
double
distance
READ
distance
WRITE
setDistance
NOTIFY
distanceChanged
)
///< Distance to previous waypoint
Q_PROPERTY
(
bool
friendlyEditAllowed
READ
friendlyEditAllowed
NOTIFY
friendlyEditAllowedChanged
)
Q_PROPERTY
(
bool
homePosition
READ
homePosition
CONSTANT
)
///< true: This item is being used as a home position indicator
Q_PROPERTY
(
bool
homePositionValid
READ
homePositionValid
WRITE
setHomePositionValid
NOTIFY
homePositionValidChanged
)
///< true: Home position should be shown
Q_PROPERTY
(
bool
isCurrentItem
READ
isCurrentItem
WRITE
setIsCurrentItem
NOTIFY
isCurrentItemChanged
)
Q_PROPERTY
(
bool
rawEdit
READ
rawEdit
WRITE
setRawEdit
NOTIFY
rawEditChanged
)
///< true: raw item editing with all params
Q_PROPERTY
(
bool
relativeAltitude
READ
relativeAltitude
NOTIFY
frameChanged
)
Q_PROPERTY
(
int
sequenceNumber
READ
sequenceNumber
WRITE
setSequenceNumber
NOTIFY
sequenceNumberChanged
)
Q_PROPERTY
(
bool
standaloneCoordinate
READ
standaloneCoordinate
NOTIFY
commandChanged
)
Q_PROPERTY
(
bool
specifiesCoordinate
READ
specifiesCoordinate
NOTIFY
commandChanged
)
Q_PROPERTY
(
bool
showHomePosition
READ
showHomePosition
WRITE
setShowHomePosition
NOTIFY
showHomePositionChanged
)
// These properties are used to display the editing ui
Q_PROPERTY
(
QmlObjectListModel
*
checkboxFacts
READ
checkboxFacts
NOTIFY
uiModelChanged
)
...
...
@@ -112,12 +113,12 @@ public:
double
distance
(
void
)
const
{
return
_distance
;
}
bool
friendlyEditAllowed
(
void
)
const
;
bool
homePosition
(
void
)
const
{
return
_homePositionSpecialCase
;
}
bool
homePositionValid
(
void
)
const
{
return
_homePositionValid
;
}
bool
isCurrentItem
(
void
)
const
{
return
_isCurrentItem
;
}
bool
rawEdit
(
void
)
const
;
int
sequenceNumber
(
void
)
const
{
return
_sequenceNumber
;
}
bool
standaloneCoordinate
(
void
)
const
;
bool
specifiesCoordinate
(
void
)
const
;
bool
showHomePosition
(
void
)
const
{
return
_showHomePosition
;
}
QmlObjectListModel
*
textFieldFacts
(
void
);
...
...
@@ -137,8 +138,8 @@ public:
void
setCommand
(
MavlinkQmlSingleton
::
Qml_MAV_CMD
command
);
void
setHomePositionValid
(
bool
homePositionValid
);
void
setHomePositionSpecialCase
(
bool
homePositionSpecialCase
)
{
_homePositionSpecialCase
=
homePositionSpecialCase
;
}
void
setShowHomePosition
(
bool
showHomePosition
);
void
setAltDifference
(
double
altDifference
);
void
setAltPercent
(
double
altPercent
);
...
...
@@ -170,8 +171,9 @@ public:
// C++ only methods
void
save
(
Q
TextStream
&
saveStream
);
void
save
(
Q
JsonObject
&
json
);
bool
load
(
QTextStream
&
loadStream
);
bool
load
(
const
QJsonObject
&
json
,
QString
&
errorString
);
bool
relativeAltitude
(
void
)
{
return
frame
()
==
MAV_FRAME_GLOBAL_RELATIVE_ALT
;
}
...
...
@@ -191,11 +193,11 @@ signals:
void
frameChanged
(
int
frame
);
void
friendlyEditAllowedChanged
(
bool
friendlyEditAllowed
);
void
headingDegreesChanged
(
double
heading
);
void
homePositionValidChanged
(
bool
homePostionValid
);
void
isCurrentItemChanged
(
bool
isCurrentItem
);
void
rawEditChanged
(
bool
rawEdit
);
void
sequenceNumberChanged
(
int
sequenceNumber
);
void
uiModelChanged
(
void
);
void
showHomePositionChanged
(
bool
showHomePosition
);
private
slots
:
void
_setDirtyFromSignal
(
void
);
...
...
@@ -223,7 +225,7 @@ private:
double
_azimuth
;
///< Azimuth to previous waypoint
double
_distance
;
///< Distance to previous waypoint
bool
_homePositionSpecialCase
;
///< true: This item is being used as a ui home position indicator
bool
_
homePositionValid
;
///< true: Home psition should be displayed
bool
_
showHomePosition
;
Fact
_altitudeRelativeToHomeFact
;
Fact
_autoContinueFact
;
...
...
@@ -260,6 +262,18 @@ private:
bool
_syncingHeadingDegreesAndParam4
;
///< true: already in a sync signal, prevents signal loop
const
MissionCommands
*
_missionCommands
;
static
const
char
*
_itemType
;
static
const
char
*
_jsonTypeKey
;
static
const
char
*
_jsonIdKey
;
static
const
char
*
_jsonFrameKey
;
static
const
char
*
_jsonCommandKey
;
static
const
char
*
_jsonParam1Key
;
static
const
char
*
_jsonParam2Key
;
static
const
char
*
_jsonParam3Key
;
static
const
char
*
_jsonParam4Key
;
static
const
char
*
_jsonAutoContinueKey
;
static
const
char
*
_jsonCoordinateKey
;
};
QDebug
operator
<<
(
QDebug
dbg
,
const
MissionItem
&
missionItem
);
...
...
src/MissionManager/MissionItemTest.cc
View file @
51bfac2f
...
...
@@ -97,6 +97,9 @@ MissionItemTest::MissionItemTest(void)
void
MissionItemTest
::
_test
(
void
)
{
#if 0
// FIXME: Update to json
for (size_t i=0; i<sizeof(_rgItemInfo)/sizeof(_rgItemInfo[0]); i++) {
const ItemInfo_t* info = &_rgItemInfo[i];
const ItemExpected_t* expected = &_rgItemExpected[i];
...
...
@@ -177,6 +180,7 @@ void MissionItemTest::_test(void)
delete item;
delete loadedItem;
}
#endif
}
void
MissionItemTest
::
_testDefaultValues
(
void
)
...
...
src/MissionManager/MissionManagerTest.cc
View file @
51bfac2f
...
...
@@ -52,7 +52,6 @@ void MissionManagerTest::_writeItems(MockLinkMissionItemHandler::FailureMode_t f
// Editor has a home position item on the front, so we do the same
MissionItem
*
homeItem
=
new
MissionItem
(
NULL
/* Vehicle */
,
this
);
homeItem
->
setHomePositionSpecialCase
(
true
);
homeItem
->
setHomePositionValid
(
false
);
homeItem
->
setCommand
(
MavlinkQmlSingleton
::
MAV_CMD_NAV_WAYPOINT
);
homeItem
->
setCoordinate
(
QGeoCoordinate
(
47.3769
,
8.549444
,
0
));
homeItem
->
setSequenceNumber
(
0
);
...
...
src/QGCApplication.cc
View file @
51bfac2f
...
...
@@ -129,8 +129,9 @@ const char* QGCApplication::_settingsVersionKey = "SettingsVersion";
const
char
*
QGCApplication
::
_promptFlightDataSave
=
"PromptFLightDataSave"
;
const
char
*
QGCApplication
::
_promptFlightDataSaveNotArmed
=
"PromptFLightDataSaveNotArmed"
;
const
char
*
QGCApplication
::
_styleKey
=
"StyleIsDark"
;
const
char
*
QGCApplication
::
_defaultMapPositionLatKey
=
"DefaultMapPositionLat"
;
const
char
*
QGCApplication
::
_defaultMapPositionLonKey
=
"DefaultMapPositionLon"
;
const
char
*
QGCApplication
::
_lastKnownHomePositionLatKey
=
"LastKnownHomePositionLat"
;
const
char
*
QGCApplication
::
_lastKnownHomePositionLonKey
=
"LastKnownHomePositionLon"
;
const
char
*
QGCApplication
::
_lastKnownHomePositionAltKey
=
"LastKnownHomePositionAlt"
;
const
char
*
QGCApplication
::
_darkStyleFile
=
":/res/styles/style-dark.css"
;
const
char
*
QGCApplication
::
_lightStyleFile
=
":/res/styles/style-light.css"
;
...
...
@@ -186,7 +187,7 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting)
#endif
,
_toolbox
(
NULL
)
,
_bluetoothAvailable
(
false
)
,
_
defaultMapPosition
(
37.803784
,
-
122.462276
)
,
_
lastKnownHomePosition
(
37.803784
,
-
122.462276
,
0.0
)
{
Q_ASSERT
(
_app
==
NULL
);
_app
=
this
;
...
...
@@ -375,8 +376,9 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting)
QFile
::
remove
(
ParameterLoader
::
parameterCacheFile
());
}
_defaultMapPosition
.
setLatitude
(
settings
.
value
(
_defaultMapPositionLatKey
,
37.803784
).
toDouble
());
_defaultMapPosition
.
setLongitude
(
settings
.
value
(
_defaultMapPositionLonKey
,
-
122.462276
).
toDouble
());
_lastKnownHomePosition
.
setLatitude
(
settings
.
value
(
_lastKnownHomePositionLatKey
,
37.803784
).
toDouble
());
_lastKnownHomePosition
.
setLongitude
(
settings
.
value
(
_lastKnownHomePositionLonKey
,
-
122.462276
).
toDouble
());
_lastKnownHomePosition
.
setAltitude
(
settings
.
value
(
_lastKnownHomePositionAltKey
,
0.0
).
toDouble
());
// Initialize Bluetooth
#ifdef QGC_ENABLE_BLUETOOTH
...
...
@@ -773,11 +775,12 @@ void QGCApplication::_showSetupVehicleComponent(VehicleComponent* vehicleCompone
QMetaObject
::
invokeMethod
(
_rootQmlObject
(),
"showSetupVehicleComponent"
,
Q_RETURN_ARG
(
QVariant
,
varReturn
),
Q_ARG
(
QVariant
,
varComponent
));
}
void
QGCApplication
::
set
DefaultMapPosition
(
QGeoCoordinate
&
defaultMap
Position
)
void
QGCApplication
::
set
LastKnownHomePosition
(
QGeoCoordinate
&
lastKnownHome
Position
)
{
QSettings
settings
;
settings
.
setValue
(
_defaultMapPositionLatKey
,
defaultMapPosition
.
latitude
());
settings
.
setValue
(
_defaultMapPositionLonKey
,
defaultMapPosition
.
longitude
());
_defaultMapPosition
=
defaultMapPosition
;
settings
.
setValue
(
_lastKnownHomePositionLatKey
,
lastKnownHomePosition
.
latitude
());
settings
.
setValue
(
_lastKnownHomePositionLonKey
,
lastKnownHomePosition
.
longitude
());
settings
.
setValue
(
_lastKnownHomePositionAltKey
,
lastKnownHomePosition
.
altitude
());
_lastKnownHomePosition
=
lastKnownHomePosition
;
}
src/QGCApplication.h
View file @
51bfac2f
...
...
@@ -121,8 +121,8 @@ public:
/// Do we have Bluetooth Support?
bool
isBluetoothAvailable
()
{
return
_bluetoothAvailable
;
}
QGeoCoordinate
defaultMapPosition
(
void
)
{
return
_defaultMap
Position
;
}
void
set
DefaultMapPosition
(
QGeoCoordinate
&
defaultMap
Position
);
QGeoCoordinate
lastKnownHomePosition
(
void
)
{
return
_lastKnownHome
Position
;
}
void
set
LastKnownHomePosition
(
QGeoCoordinate
&
lastKnownHome
Position
);
public
slots
:
/// You can connect to this slot to show an information message box from a different thread.
...
...
@@ -207,15 +207,16 @@ private:
bool
_bluetoothAvailable
;
QGeoCoordinate
_
defaultMap
Position
;
///< Map position when all other sources fail
QGeoCoordinate
_
lastKnownHome
Position
;
///< Map position when all other sources fail
static
const
char
*
_settingsVersionKey
;
///< Settings key which hold settings version
static
const
char
*
_deleteAllSettingsKey
;
///< If this settings key is set on boot, all settings will be deleted
static
const
char
*
_promptFlightDataSave
;
///< Settings key for promptFlightDataSave
static
const
char
*
_promptFlightDataSaveNotArmed
;
///< Settings key for promptFlightDataSaveNotArmed
static
const
char
*
_styleKey
;
///< Settings key for UI style
static
const
char
*
_defaultMapPositionLatKey
;
///< Settings key for default map location
static
const
char
*
_defaultMapPositionLonKey
;
///< Settings key for default map location
static
const
char
*
_lastKnownHomePositionLatKey
;
static
const
char
*
_lastKnownHomePositionLonKey
;
static
const
char
*
_lastKnownHomePositionAltKey
;
/// Unit Test have access to creating and destroying singletons
friend
class
UnitTest
;
...
...
src/QmlControls/MissionCommandDialog.qml
View file @
51bfac2f
...
...
@@ -73,6 +73,7 @@ QGCViewDialog {
anchors.bottom
:
parent
.
bottom
spacing
:
ScreenTools
.
defaultFontPixelHeight
/
2
orientation
:
ListView
.
Vertical
clip
:
true
delegate
:
Rectangle
{
width
:
parent
.
width
...
...
@@ -90,8 +91,9 @@ QGCViewDialog {
anchors.top
:
parent
.
top
QGCLabel
{
text
:
mavCmdInfo
.
friendlyName
color
:
textColor
text
:
mavCmdInfo
.
friendlyName
color
:
textColor
font.weight
:
Font
.
DemiBold
}
QGCLabel
{
...
...
src/QmlControls/MissionItemEditor.qml
View file @
51bfac2f
...
...
@@ -22,6 +22,7 @@ Rectangle {
signal
remove
signal
removeAll
signal
insert
(
int
i
)
signal
moveHomeToMapCenter
height
:
innerItem
.
height
+
(
_margin
*
3
)
color
:
missionItem
.
isCurrentItem
?
qgcPal
.
buttonHighlight
:
qgcPal
.
windowShade
...
...
@@ -152,7 +153,7 @@ Rectangle {
anchors.fill
:
commandPicker
visible
:
missionItem
.
sequenceNumber
==
0
||
!
missionItem
.
isCurrentItem
verticalAlignment
:
Text
.
AlignVCenter
text
:
missionItem
.
sequenceNumber
==
0
?
"
Home
"
:
missionItem
.
commandName
text
:
missionItem
.
sequenceNumber
==
0
?
"
Home
Position
"
:
missionItem
.
commandName
color
:
qgcPal
.
buttonText
}
...
...
@@ -164,7 +165,7 @@ Rectangle {
anchors.right
:
parent
.
right
height
:
valuesItem
.
height
color
:
qgcPal
.
windowShadeDark
visible
:
missionItem
.
sequenceNumber
!=
0
&&
missionItem
.
isCurrentItem
visible
:
missionItem
.
isCurrentItem
radius
:
_radius
Item
{
...
...
@@ -185,9 +186,11 @@ Rectangle {
QGCLabel
{
width
:
parent
.
width
wrapMode
:
Text
.
WordWrap
text
:
missionItem
.
rawEdit
?
"
Provides advanced access to all commands/parameters. Be very careful!
"
:
missionItem
.
commandDescription
text
:
missionItem
.
sequenceNumber
==
0
?
"
Planned home position.
"
:
(
missionItem
.
rawEdit
?
"
Provides advanced access to all commands/parameters. Be very careful!
"
:
missionItem
.
commandDescription
)
}
Repeater
{
...
...
@@ -254,6 +257,13 @@ Rectangle {
fact
:
object
}
}
QGCButton
{
text
:
"
Move Home to map center
"
visible
:
missionItem
.
homePosition
onClicked
:
moveHomeToMapCenter
()
anchors.horizontalCenter
:
parent
.
horizontalCenter
}
}
// Column
}
// Item
}
// Rectangle
...
...
src/QmlControls/QGroundControlQmlGlobal.h
View file @
51bfac2f
...
...
@@ -75,7 +75,7 @@ public:
Q_PROPERTY
(
Fact
*
offlineEditingFirmwareType
READ
offlineEditingFirmwareType
CONSTANT
)
Q_PROPERTY
(
QGeoCoordinate
defaultMapPosition
READ
defaultMap
Position
CONSTANT
)
Q_PROPERTY
(
QGeoCoordinate
lastKnownHomePosition
READ
lastKnownHome
Position
CONSTANT
)
Q_INVOKABLE
void
saveGlobalSetting
(
const
QString
&
key
,
const
QString
&
value
);
Q_INVOKABLE
QString
loadGlobalSetting
(
const
QString
&
key
,
const
QString
&
defaultValue
);
...
...
@@ -113,7 +113,7 @@ public:
bool
isVersionCheckEnabled
()
{
return
_toolbox
->
mavlinkProtocol
()
->
versionCheckEnabled
();
}
int
mavlinkSystemID
()
{
return
_toolbox
->
mavlinkProtocol
()
->
getSystemId
();
}
QGeoCoordinate
defaultMapPosition
()
{
return
qgcApp
()
->
defaultMap
Position
();
}
QGeoCoordinate
lastKnownHomePosition
()
{
return
qgcApp
()
->
lastKnownHome
Position
();
}
Fact
*
offlineEditingFirmwareType
()
{
return
&
_offlineEditingFirmwareTypeFact
;
}
...
...
src/Vehicle/Vehicle.cc
View file @
51bfac2f
...
...
@@ -326,7 +326,7 @@ void Vehicle::_handleHomePosition(mavlink_message_t& message)
if
(
emitHomePositionChanged
)
{
qCDebug
(
VehicleLog
)
<<
"New home position"
<<
newHomePosition
;
qgcApp
()
->
set
DefaultMap
Position
(
_homePosition
);
qgcApp
()
->
set
LastKnownHome
Position
(
_homePosition
);
emit
homePositionChanged
(
_homePosition
);
}
if
(
emitHomePositionAvailableChanged
)
{
...
...
src/VehicleSetup/SetupViewTest.cc
View file @
51bfac2f
...
...
@@ -30,14 +30,13 @@
#include "QGCApplication.h"
void
SetupViewTest
::
_clickThrough_test
(
void
)
{
{
_createMainWindow
();
_connectMockLink
();
AutoPilotPlugin
*
autopilot
=
qgcApp
()
->
toolbox
()
->
multiVehicleManager
()
->
activeVehicle
()
->
autopilotPlugin
();
Q_ASSERT
(
autopilot
);
_createMainWindow
();
// Switch to the Setup view
qgcApp
()
->
showSetupView
();
QTest
::
qWait
(
1000
);
...
...
src/qgcunittest/UnitTestList.cc
View file @
51bfac2f
...
...
@@ -38,7 +38,6 @@
#include "SetupViewTest.h"
#include "MavlinkLogTest.h"
UT_REGISTER_TEST
(
SetupViewTest
)
UT_REGISTER_TEST
(
FactSystemTestGeneric
)
UT_REGISTER_TEST
(
FactSystemTestPX4
)
UT_REGISTER_TEST
(
FileDialogTest
)
...
...
@@ -65,3 +64,5 @@ UT_REGISTER_TEST(RadioConfigTest)
// time to debug.
//UT_REGISTER_TEST(TCPLinkUnitTest)
// Windows based unit tests are not working correctly. Needs major reword to support.
//UT_REGISTER_TEST(SetupViewTest)
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