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
0adf8caa
Commit
0adf8caa
authored
Oct 16, 2015
by
Don Gagne
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Mission Editor usability changes
parent
92cc42a1
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
805 additions
and
681 deletions
+805
-681
qgroundcontrol.qrc
qgroundcontrol.qrc
+1
-0
FlightDisplayView.qml
src/FlightDisplay/FlightDisplayView.qml
+26
-22
FlightMap.qml
src/FlightMap/FlightMap.qml
+7
-11
MissionEditor.qml
src/MissionEditor/MissionEditor.qml
+565
-494
MissionEditorController.cc
src/MissionEditor/MissionEditorController.cc
+3
-2
MissionItem.cc
src/MissionItem.cc
+145
-88
MissionItem.h
src/MissionItem.h
+29
-13
DropButton.qml
src/QmlControls/DropButton.qml
+1
-1
MissionItemEditor.qml
src/QmlControls/MissionItemEditor.qml
+26
-49
MissionItemIndexLabel.qml
src/QmlControls/MissionItemIndexLabel.qml
+2
-1
No files found.
qgroundcontrol.qrc
View file @
0adf8caa
...
...
@@ -70,6 +70,7 @@
<file alias="Help.svg">src/FlightMap/Images/Help.svg</file>
<file alias="MapCenter.svg">src/FlightMap/Images/MapCenter.svg</file>
<file alias="MapSync.svg">src/FlightMap/Images/MapSync.svg</file>
<file alias="MapSyncChanged.svg">src/FlightMap/Images/MapSyncChanged.svg</file>
<file alias="MapType.svg">src/FlightMap/Images/MapType.svg</file>
<file alias="MapHome.svg">src/FlightMap/Images/MapHome.svg</file>
<file alias="MapAddMission.svg">src/FlightMap/Images/MapAddMission.svg</file>
...
...
src/FlightDisplay/FlightDisplayView.qml
View file @
0adf8caa
...
...
@@ -55,8 +55,7 @@ Item {
property
var
_activeVehicle
:
multiVehicleManager
.
activeVehicle
readonly
property
real
_defaultLatitude
:
37.803784
readonly
property
real
_defaultLongitude
:
-
122.462276
readonly
property
var
_defaultVehicleCoordinate
:
QtPositioning
.
coordinate
(
37.803784
,
-
122.462276
)
readonly
property
real
_defaultRoll
:
0
readonly
property
real
_defaultPitch
:
0
readonly
property
real
_defaultHeading
:
0
...
...
@@ -72,8 +71,7 @@ Item {
property
real
_pitch
:
_activeVehicle
?
(
isNaN
(
_activeVehicle
.
pitch
)
?
_defaultPitch
:
_activeVehicle
.
pitch
)
:
_defaultPitch
property
real
_heading
:
_activeVehicle
?
(
isNaN
(
_activeVehicle
.
heading
)
?
_defaultHeading
:
_activeVehicle
.
heading
)
:
_defaultHeading
property
real
_latitude
:
_activeVehicle
?
((
_activeVehicle
.
latitude
===
0
)
?
_defaultLatitude
:
_activeVehicle
.
latitude
)
:
_defaultLatitude
property
real
_longitude
:
_activeVehicle
?
((
_activeVehicle
.
longitude
===
0
)
?
_defaultLongitude
:
_activeVehicle
.
longitude
)
:
_defaultLongitude
property
var
_vehicleCoordinate
:
_activeVehicle
?
_activeVehicle
.
coordinate
:
_defaultVehicleCoordinate
property
real
_altitudeWGS84
:
_activeVehicle
?
_activeVehicle
.
altitudeWGS84
:
_defaultAltitudeWGS84
property
real
_groundSpeed
:
_activeVehicle
?
_activeVehicle
.
groundSpeed
:
_defaultGroundSpeed
...
...
@@ -82,14 +80,20 @@ Item {
property
bool
_showMap
:
getBool
(
QGroundControl
.
flightMapSettings
.
loadMapSetting
(
flightMap
.
mapName
,
_showMapBackgroundKey
,
"
1
"
))
FlightDisplayViewController
{
id
:
_controller
;
}
FlightDisplayViewController
{
id
:
_controller
}
ExclusiveGroup
{
id
:
_dropButtonsExclusiveGroup
}
// Validate _showMap setting
Component.onCompleted
:
_setShowMap
(
_showMap
)
Component.onCompleted
:
{
// We have to be careful to not reference root properties in a function which is in a subcomponent
// until the root component has completed loading. Otherwise you get undefined references.
flightMap
.
rootLoadCompleted
=
true
flightMap
.
updateMapPosition
(
true
/* force */
)
_setShowMap
(
_showMap
)
}
function
getBool
(
value
)
{
return
value
===
'
0
'
?
false
:
true
;
...
...
@@ -104,24 +108,24 @@ Item {
QGroundControl
.
flightMapSettings
.
saveMapSetting
(
flightMap
.
mapName
,
_showMapBackgroundKey
,
setBool
(
_showMap
))
}
FlightMap
{
id
:
flightMap
anchors.fill
:
parent
mapName
:
_mapName
visible
:
_showMap
latitude
:
root
.
_defaultCoordinate
.
latitude
longitude
:
root
.
_defaultCoordinate
.
longitude
property
real
rootLatitude
:
root
.
_latitude
property
real
rootLongitude
:
root
.
_longitude
Component.onCompleted
:
updateMapPosition
(
true
/* force */
)
property
var
rootVehicleCoordinate
:
_vehicleCoordinate
property
bool
rootLoadCompleted
:
false
onRootLatitudeChanged
:
updateMapPosition
(
false
/* force */
)
onRootLongitudeChanged
:
updateMapPosition
(
false
/* force */
)
onRootVehicleCoordinateChanged
:
updateMapPosition
(
false
/* force */
)
function
updateMapPosition
(
force
)
{
if
(
_followVehicle
||
force
)
{
latitude
=
root
.
_
latitude
longitude
=
root
.
_
longitude
if
(
(
_followVehicle
||
force
)
&&
rootLoadCompleted
)
{
flightMap
.
latitude
=
root
.
_vehicleCoordinate
.
latitude
flightMap
.
longitude
=
root
.
_vehicleCoordinate
.
longitude
}
}
...
...
src/FlightMap/FlightMap.qml
View file @
0adf8caa
...
...
@@ -59,10 +59,13 @@ Map {
readonly
property
real
zOrderWidgets
:
100
///< z order value to widgets, for example: zoom controls, hud widgetss
readonly
property
real
zOrderMapItems
:
50
///< z order value for map items, for example: mission item indicators
readonly
property
real
maxZoomLevel
:
20
zoomLevel
:
18
center
:
QtPositioning
.
coordinate
(
lat
,
lon
)
gesture.flickDeceleration
:
3000
gesture.enabled
:
interactive
gesture.activeGestures
:
MapGestureArea
.
ZoomGesture
|
MapGestureArea
.
PanGesture
|
MapGestureArea
.
FlickGesture
plugin
:
Plugin
{
name
:
"
QGroundControl
"
}
...
...
@@ -295,11 +298,4 @@ Map {
}
}
*/
MouseArea
{
//-- TODO: Check if this is still needed when we switch to 5.5.1
//-- Workaround for QTBUG-46388 (Pinch zoom doesn't work without it on mobile)
anchors.fill
:
parent
}
}
// Map
src/MissionEditor/MissionEditor.qml
View file @
0adf8caa
...
...
@@ -45,9 +45,13 @@ QGCView {
readonly
property
int
_decimalPlaces
:
7
readonly
property
real
_horizontalMargin
:
ScreenTools
.
defaultFontPixelWidth
/
2
readonly
property
real
_
verticalMargin
:
ScreenTools
.
defaultFontPixelHeight
/
2
readonly
property
real
_
margin
:
ScreenTools
.
defaultFontPixelHeight
/
2
readonly
property
var
_activeVehicle
:
multiVehicleManager
.
activeVehicle
readonly
property
real
_editFieldWidth
:
ScreenTools
.
defaultFontPixelWidth
*
16
readonly
property
real
_rightPanelWidth
:
ScreenTools
.
defaultFontPixelWidth
*
30
readonly
property
real
_rightPanelOpacity
:
0.8
readonly
property
int
_toolButtonCount
:
6
readonly
property
int
_addMissionItemsButtonAutoOffTimeout
:
10000
property
var
_missionItems
:
_controller
.
missionItems
...
...
@@ -59,9 +63,11 @@ QGCView {
property
var
liveHomePositionAvailable
:
_controller
.
liveHomePositionAvailable
property
var
homePosition
:
offlineHomePosition
// live or offline depending on state
property
bool
_syncNeeded
:
_controller
.
missionItems
.
dirty
MissionEditorController
{
id
:
_controller
}
QGCPalette
{
id
:
_
qgcPal
;
colorGroupEnabled
:
enabled
}
QGCPalette
{
id
:
qgcPal
;
colorGroupEnabled
:
enabled
}
ExclusiveGroup
{
id
:
_mapTypeButtonsExclusiveGroup
...
...
@@ -69,7 +75,6 @@ QGCView {
ExclusiveGroup
{
id
:
_dropButtonsExclusiveGroup
onCurrentChanged
:
console
.
log
(
"
Current button
"
,
current
)
}
function
setCurrentItem
(
index
)
{
...
...
@@ -107,10 +112,7 @@ QGCView {
FlightMap
{
id
:
editorMap
anchors.left
:
parent
.
left
anchors.right
:
missionItemView
.
left
anchors.top
:
parent
.
top
anchors.bottom
:
parent
.
bottom
anchors.fill
:
parent
mapName
:
"
MissionEditor
"
Component.onCompleted
:
{
...
...
@@ -118,6 +120,29 @@ QGCView {
longitude
=
homePosition
.
longitude
}
readonly
property
real
animationDuration
:
500
Behavior
on
zoomLevel
{
NumberAnimation
{
duration
:
editorMap
.
animationDuration
easing.type
:
Easing
.
InOutQuad
}
}
Behavior
on
latitude
{
NumberAnimation
{
duration
:
editorMap
.
animationDuration
easing.type
:
Easing
.
InOutQuad
}
}
Behavior
on
longitude
{
NumberAnimation
{
duration
:
editorMap
.
animationDuration
easing.type
:
Easing
.
InOutQuad
}
}
MouseArea
{
anchors.fill
:
parent
...
...
@@ -130,227 +155,55 @@ QGCView {
offlineHomePosition
=
coordinate
}
else
if
(
addMissionItemsButton
.
checked
)
{
var
index
=
_controller
.
addMissionItem
(
coordinate
)
addMissionItemsButtonAutoOffTimer
.
start
()
setCurrentItem
(
index
)
}
else
{
editorMap
.
zoomLevel
=
editorMap
.
maxZoomLevel
-
2
}
}
}
Rectangle
{
anchors.horizontalCenter
:
parent
.
horizontalCenter
anchors.bottom
:
parent
.
bottom
width
:
parent
.
width
*
0.75
height
:
syncNeededText
.
height
+
(
ScreenTools
.
defaultFontPixelWidth
*
2
)
border.width
:
1
border.color
:
"
white
"
color
:
"
black
"
opacity
:
0.75
visible
:
_controller
.
missionItems
.
dirty
QGCLabel
{
id
:
syncNeededText
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.top
:
parent
.
top
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
wrapMode
:
Text
.
WordWrap
horizontalAlignment
:
Text
.
AlignHCenter
verticalAlignment
:
Text
.
AlignVCenter
font.pixelSize
:
ScreenTools
.
mediumFontPixelSize
text
:
"
You have unsaved changes. Be sure to use the Sync tool to save when ready.
"
}
}
RoundButton
{
id
:
addMissionItemsButton
anchors.rightMargin
:
ScreenTools
.
defaultFontPixelWidth
anchors.right
:
homePositionManagerButton
.
left
anchors.top
:
helpButton
.
top
buttonImage
:
"
/qmlimages/MapAddMission.svg
"
exclusiveGroup
:
_dropButtonsExclusiveGroup
}
RoundButton
{
id
:
homePositionManagerButton
anchors.rightMargin
:
ScreenTools
.
defaultFontPixelWidth
anchors.right
:
centerMapButton
.
left
anchors.top
:
helpButton
.
top
buttonImage
:
"
/qmlimages/MapHome.svg
"
exclusiveGroup
:
_dropButtonsExclusiveGroup
}
DropButton
{
id
:
centerMapButton
anchors.rightMargin
:
ScreenTools
.
defaultFontPixelWidth
anchors.right
:
syncButton
.
left
anchors.top
:
helpButton
.
top
dropDirection
:
dropDown
buttonImage
:
"
/qmlimages/MapCenter.svg
"
viewportMargins
:
ScreenTools
.
defaultFontPixelWidth
/
2
exclusiveGroup
:
_dropButtonsExclusiveGroup
dropDownComponent
:
Component
{
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCButton
{
text
:
"
Home
"
onClicked
:
{
centerMapButton
.
hideDropDown
()
editorMap
.
center
=
QtPositioning
.
coordinate
(
homePosition
.
latitude
,
homePosition
.
longitude
)
}
}
QGCButton
{
text
:
"
Vehicle
"
enabled
:
activeVehicle
&&
activeVehicle
.
latitude
!=
0
&&
activeVehicle
.
longitude
!=
0
property
var
activeVehicle
:
multiVehicleManager
.
activeVehicle
onClicked
:
{
centerMapButton
.
hideDropDown
()
editorMap
.
latitude
=
activeVehicle
.
latitude
editorMap
.
longitude
=
activeVehicle
.
longitude
}
}
/*
This code will need to wait for Qml 5.5 support since Map.visibleRegion is only in Qt 5.5
QGCButton {
text: "All Items"
onClicked: {
centerMapButton.hideDropDown()
// Begin with only the home position in the region
var region = QtPositioning.rectangle(QtPositioning.coordinate(homePosition.latitude, homePosition.longitude),
QtPositioning.coordinate(homePosition.latitude, homePosition.longitude))
// Now expand the region to include all mission items
for (var i=0; i<_missionItems.count; i++) {
var missionItem = _missionItems.get(i)
region.topLeft.latitude = Math.max(missionItem.coordinate.latitude, region.topLeft.latitude)
region.topLeft.longitude = Math.min(missionItem.coordinate.longitude, region.topLeft.longitude)
region.topRight.latitude = Math.max(missionItem.coordinate.latitude, region.topRight.latitude)
region.topRight.longitude = Math.max(missionItem.coordinate.longitude, region.topRight.longitude)
region.bottomLeft.latitude = Math.min(missionItem.coordinate.latitude, region.bottomLeft.latitude)
region.bottomLeft.longitude = Math.min(missionItem.coordinate.longitude, region.bottomLeft.longitude)
region.bottomRight.latitude = Math.min(missionItem.coordinate.latitude, region.bottomRight.latitude)
region.bottomRight.longitude = Math.max(missionItem.coordinate.longitude, region.bottomRight.longitude)
}
editorMap.visibleRegion = region
}
}
*/
}
}
}
DropButton
{
id
:
syncButton
anchors.rightMargin
:
ScreenTools
.
defaultFontPixelWidth
anchors.right
:
mapTypeButton
.
left
anchors.top
:
helpButton
.
top
dropDirection
:
dropDown
buttonImage
:
"
/qmlimages/MapSync.svg
"
viewportMargins
:
ScreenTools
.
defaultFontPixelWidth
/
2
exclusiveGroup
:
_dropButtonsExclusiveGroup
dropDownComponent
:
Component
{
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCButton
{
text
:
"
Load from vehicle
"
enabled
:
_activeVehicle
&&
!
_activeVehicle
.
missionManager
.
inProgress
onClicked
:
{
syncButton
.
hideDropDown
()
_controller
.
getMissionItems
()
}
}
QGCButton
{
text
:
"
Save to vehicle
"
enabled
:
_activeVehicle
&&
!
_activeVehicle
.
missionManager
.
inProgress
onClicked
:
{
syncButton
.
hideDropDown
()
_controller
.
setMissionItems
()
}
}
QGCButton
{
text
:
"
Load from file...
"
onClicked
:
{
syncButton
.
hideDropDown
()
_controller
.
loadMissionFromFile
()
}
}
QGCButton
{
text
:
"
Save to file...
"
// We use this item to support dragging since dragging a MapQuickItem just doesn't seem to work
Item
{
id
:
itemEditor
x
:
missionItemIndicator
?
(
missionItemIndicator
.
x
+
missionItemIndicator
.
anchorPoint
.
x
-
(
itemEditor
.
width
/
2
))
:
100
y
:
missionItemIndicator
?
(
missionItemIndicator
.
y
+
missionItemIndicator
.
anchorPoint
.
y
-
(
itemEditor
.
height
/
2
))
:
100
width
:
ScreenTools
.
defaultFontPixelHeight
*
7
height
:
ScreenTools
.
defaultFontPixelHeight
*
7
visible
:
false
z
:
editorMap
.
zOrderMapItems
+
1
// Above item icons
property
var
missionItem
property
var
missionItemIndicator
property
real
heading
:
missionItem
?
missionItem
.
heading
:
0
Drag.active
:
itemDrag
.
drag
.
active
Drag.hotSpot.x
:
width
/
2
Drag.hotSpot.y
:
height
/
2
onClicked
:
{
syncButton
.
hideDropDown
()
_controller
.
saveMissionToFile
()
}
}
}
}
MissionItemIndexLabel
{
x
:
(
itemEditor
.
width
/
2
)
-
(
width
/
2
)
y
:
(
itemEditor
.
height
/
2
)
-
(
height
/
2
)
label
:
itemEditor
.
missionItemIndicator
?
itemEditor
.
missionItemIndicator
.
label
:
""
isCurrentItem
:
true
}
DropButton
{
id
:
mapTypeButton
anchors.rightMargin
:
ScreenTools
.
defaultFontPixelWidth
anchors.right
:
helpButton
.
left
anchors.top
:
helpButton
.
top
dropDirection
:
dropDown
buttonImage
:
"
/qmlimages/MapType.svg
"
viewportMargins
:
ScreenTools
.
defaultFontPixelWidth
/
2
exclusiveGroup
:
_dropButtonsExclusiveGroup
dropDownComponent
:
Component
{
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
Repeater
{
model
:
QGroundControl
.
flightMapSettings
.
mapTypes
MouseArea
{
id
:
itemDrag
anchors.fill
:
parent
drag.target
:
parent
QGCButton
{
checkable
:
true
checked
:
editorMap
.
mapType
==
text
text
:
modelData
exclusiveGroup
:
_mapTypeButtonsExclusiveGroup
property
bool
dragActive
:
drag
.
active
onClicked
:
{
editorMap
.
mapType
=
text
checked
=
true
mapTypeButton
.
hideDropDown
()
}
}
onDragActiveChanged
:
{
if
(
!
drag
.
active
)
{
var
point
=
Qt
.
point
(
itemEditor
.
x
+
(
itemEditor
.
width
/
2
),
itemEditor
.
y
+
(
itemEditor
.
height
/
2
))
itemEditor
.
missionItem
.
coordinate
=
editorMap
.
toCoordinate
(
point
)
}
}
}
}
RoundButton
{
id
:
helpButton
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.right
:
parent
.
right
anchors.top
:
parent
.
top
buttonImage
:
"
/qmlimages/Help.svg
"
exclusiveGroup
:
_dropButtonsExclusiveGroup
}
// Add the mission items to the map
MapItemView
{
model
:
_controller
.
missionItems
...
...
@@ -361,14 +214,36 @@ QGCView {
label
:
object
.
sequenceNumber
==
0
?
(
liveHomePositionAvailable
?
"
H
"
:
"
F
"
)
:
object
.
sequenceNumber
isCurrentItem
:
!
homePositionManagerButton
.
checked
&&
object
.
isCurrentItem
coordinate
:
object
.
coordinate
z
:
2
z
:
editorMap
.
zOrderMapItems
visible
:
object
.
specifiesCoordinate
onClicked
:
{
setCurrentItem
(
object
.
sequenceNumber
)
missionItemEditorButton
.
checked
onClicked
:
setCurrentItem
(
object
.
sequenceNumber
)
Connections
{
target
:
object
onIsCurrentItemChanged
:
{
if
(
isCurrentItem
)
{
// Setup our drag item
if
(
object
.
sequenceNumber
!=
0
)
{
itemEditor
.
visible
=
true
itemEditor
.
missionItem
=
Qt
.
binding
(
function
()
{
return
object
})
itemEditor
.
missionItemIndicator
=
Qt
.
binding
(
function
()
{
return
itemIndicator
})
}
else
{
itemEditor
.
visible
=
false
itemEditor
.
missionItem
=
undefined
itemEditor
.
missionItemIndicator
=
undefined
}
// Zoom the map and move to the new position
editorMap
.
zoomLevel
=
editorMap
.
maxZoomLevel
editorMap
.
latitude
=
object
.
coordinate
.
latitude
editorMap
.
longitude
=
object
.
coordinate
.
longitude
}
}
}
// These are the non-coordinate child mission items attached to this item
Row
{
anchors.top
:
parent
.
top
anchors.left
:
parent
.
right
...
...
@@ -400,8 +275,8 @@ QGCView {
delegate
:
MapPolyline
{
line.width
:
3
line.color
:
_
qgcPal
.
mapButtonHighlight
z
:
1
line.color
:
qgcPal
.
mapButtonHighlight
z
:
editorMap
.
zOrderMapItems
-
1
// Under item indicators
path
:
[
{
latitude
:
object
.
coordinate1
.
latitude
,
longitude
:
object
.
coordinate1
.
longitude
},
...
...
@@ -410,43 +285,21 @@ QGCView {
}
}
Column
{
id
:
controlWidgets
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.right
:
parent
.
left
anchors.bottom
:
parent
.
top
spacing
:
ScreenTools
.
defaultFontPixelWidth
/
2
QGCButton
{
id
:
addMode
text
:
"
+
"
checkable
:
true
}
}
}
// FlightMap
Rectangle
{
id
:
missionItemView
anchors.right
:
parent
.
right
anchors.top
:
parent
.
top
anchors.bottom
:
parent
.
bottom
width
:
ScreenTools
.
defaultFontPixelWidth
*
30
color
:
_qgcPal
.
window
Item
{
anchors.margins
:
_verticalMargin
anchors.fill
:
parent
// Mission Item Editor
Item
{
id
:
missionItemEditor
anchors.fill
:
parent
anchors.top
:
parent
.
top
anchors.bottom
:
parent
.
bottom
anchors.right
:
parent
.
right
width
:
_rightPanelWidth
visible
:
!
helpButton
.
checked
&&
!
homePositionManagerButton
.
checked
&&
_missionItems
.
count
>
1
opacity
:
_rightPanelOpacity
z
:
editorMap
.
zOrderTopMost
ListView
{
id
:
missionItemSummaryList
anchors.fill
:
parent
spacing
:
_verticalMargin
spacing
:
_margin
/
2
orientation
:
ListView
.
Vertical
model
:
_controller
.
canEdit
?
_controller
.
missionItems
:
0
...
...
@@ -481,12 +334,19 @@ QGCView {
}
// Item - Mission Item editor
// Home Position Manager
Item
{
Rectangle
{
id
:
homePositionManager
anchors.fill
:
parent
anchors.top
:
parent
.
top
anchors.bottom
:
parent
.
bottom
anchors.right
:
parent
.
right
width
:
_rightPanelWidth
visible
:
homePositionManagerButton
.
checked
color
:
qgcPal
.
window
opacity
:
_rightPanelOpacity
z
:
editorMap
.
zOrderTopMost
Column
{
anchors.margins
:
_margin
anchors.fill
:
parent
visible
:
!
liveHomePositionAvailable
...
...
@@ -668,6 +528,7 @@ QGCView {
}
// Column - Offline view
Column
{
anchors.margins
:
_margin
anchors.fill
:
parent
visible
:
liveHomePositionAvailable
...
...
@@ -742,14 +603,23 @@ QGCView {
}
}
}
// Column - Online view
}
// Item - Home Position Manager
// Help Panel
Item
{
Rectangle
{
id
:
helpPanel
anchors.fill
:
parent
anchors.top
:
parent
.
top
anchors.bottom
:
parent
.
bottom
anchors.right
:
parent
.
right
width
:
_rightPanelWidth
visible
:
!
homePositionManagerButton
.
checked
&&
(
_missionItems
.
count
==
1
||
helpButton
.
checked
)
color
:
qgcPal
.
window
opacity
:
_rightPanelOpacity
z
:
editorMap
.
zOrderTopMost
Item
{
anchors.margins
:
_margin
anchors.fill
:
parent
QGCLabel
{
id
:
helpTitle
...
...
@@ -876,9 +746,210 @@ QGCView {
text
:
"
<b>Map Type</b><br>
"
+
"
Map type options.
"
}
}
// Item - margin
}
// Item - Help Panel
}
// Item
}
// Rectangle - mission item list
RoundButton
{
id
:
addMissionItemsButton
anchors.margins
:
_margin
anchors.left
:
parent
.
left
y
:
(
parent
.
height
-
(
_toolButtonCount
*
height
)
-
((
_toolButtonCount
-
1
)
*
_margin
))
/
2
buttonImage
:
"
/qmlimages/MapAddMission.svg
"
exclusiveGroup
:
_dropButtonsExclusiveGroup
onCheckedChanged
:
{
if
(
checked
)
{
addMissionItemsButtonAutoOffTimer
.
start
()
}
else
{
addMissionItemsButtonAutoOffTimer
.
stop
()
}
}
Timer
{
id
:
addMissionItemsButtonAutoOffTimer
interval
:
_addMissionItemsButtonAutoOffTimeout
repeat
:
false
onTriggered
:
addMissionItemsButton
.
checked
=
false
}
}
RoundButton
{
id
:
homePositionManagerButton
anchors.margins
:
_margin
anchors.left
:
parent
.
left
anchors.top
:
addMissionItemsButton
.
bottom
buttonImage
:
"
/qmlimages/MapHome.svg
"
exclusiveGroup
:
_dropButtonsExclusiveGroup
z
:
editorMap
.
zOrderWidgets
}
DropButton
{
id
:
centerMapButton
anchors.margins
:
_margin
anchors.left
:
parent
.
left
anchors.top
:
homePositionManagerButton
.
bottom
dropDirection
:
dropRight
buttonImage
:
"
/qmlimages/MapCenter.svg
"
viewportMargins
:
ScreenTools
.
defaultFontPixelWidth
/
2
exclusiveGroup
:
_dropButtonsExclusiveGroup
z
:
editorMap
.
zOrderWidgets
dropDownComponent
:
Component
{
Column
{
QGCLabel
{
text
:
"
Center map:
"
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCButton
{
text
:
"
Home
"
onClicked
:
{
centerMapButton
.
hideDropDown
()
editorMap
.
center
=
QtPositioning
.
coordinate
(
homePosition
.
latitude
,
homePosition
.
longitude
)
}
}
QGCButton
{
text
:
"
Vehicle
"
enabled
:
activeVehicle
&&
activeVehicle
.
latitude
!=
0
&&
activeVehicle
.
longitude
!=
0
property
var
activeVehicle
:
multiVehicleManager
.
activeVehicle
onClicked
:
{
centerMapButton
.
hideDropDown
()
editorMap
.
latitude
=
activeVehicle
.
latitude
editorMap
.
longitude
=
activeVehicle
.
longitude
}
}
}
}
}
}
DropButton
{
id
:
syncButton
anchors.margins
:
_margin
anchors.left
:
parent
.
left
anchors.top
:
centerMapButton
.
bottom
dropDirection
:
dropRight
buttonImage
:
_syncNeeded
?
"
/qmlimages/MapSyncChanged.svg
"
:
"
/qmlimages/MapSync.svg
"
viewportMargins
:
ScreenTools
.
defaultFontPixelWidth
/
2
exclusiveGroup
:
_dropButtonsExclusiveGroup
z
:
editorMap
.
zOrderWidgets
dropDownComponent
:
Component
{
Column
{
id
:
columnHolder
spacing
:
_margin
QGCLabel
{
width
:
columnHolder
.
width
wrapMode
:
Text
.
WordWrap
text
:
_syncNeeded
?
"
You have unsaved changed to you mission. You should send to your vehicle, or save to a file:
"
:
"
Sync:
"
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCButton
{
text
:
"
Send to vehicle
"
enabled
:
_activeVehicle
&&
!
_activeVehicle
.
missionManager
.
inProgress
onClicked
:
{
syncButton
.
hideDropDown
()
_controller
.
setMissionItems
()
}
}
QGCButton
{
text
:
"
Load from vehicle
"
enabled
:
_activeVehicle
&&
!
_activeVehicle
.
missionManager
.
inProgress
onClicked
:
{
syncButton
.
hideDropDown
()
_controller
.
getMissionItems
()
}
}
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCButton
{
text
:
"
Save to file...
"
onClicked
:
{
syncButton
.
hideDropDown
()
_controller
.
saveMissionToFile
()
}
}
QGCButton
{
text
:
"
Load from file...
"
onClicked
:
{
syncButton
.
hideDropDown
()
_controller
.
loadMissionFromFile
()
}
}
}
}
}
}
DropButton
{
id
:
mapTypeButton
anchors.margins
:
_margin
anchors.left
:
parent
.
left
anchors.top
:
syncButton
.
bottom
dropDirection
:
dropRight
buttonImage
:
"
/qmlimages/MapType.svg
"
viewportMargins
:
ScreenTools
.
defaultFontPixelWidth
/
2
exclusiveGroup
:
_dropButtonsExclusiveGroup
z
:
editorMap
.
zOrderWidgets
dropDownComponent
:
Component
{
Column
{
QGCLabel
{
text
:
"
Map type:
"
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
Repeater
{
model
:
QGroundControl
.
flightMapSettings
.
mapTypes
QGCButton
{
checkable
:
true
checked
:
editorMap
.
mapType
==
text
text
:
modelData
exclusiveGroup
:
_mapTypeButtonsExclusiveGroup
onClicked
:
{
editorMap
.
mapType
=
text
checked
=
true
mapTypeButton
.
hideDropDown
()
}
}
}
}
}
}
}
RoundButton
{
id
:
helpButton
anchors.margins
:
_margin
anchors.left
:
parent
.
left
anchors.top
:
mapTypeButton
.
bottom
buttonImage
:
"
/qmlimages/Help.svg
"
exclusiveGroup
:
_dropButtonsExclusiveGroup
z
:
editorMap
.
zOrderWidgets
}
}
// FlightMap
}
// Item - split view container
}
// QGCViewPanel
}
// QGCVIew
src/MissionEditor/MissionEditorController.cc
View file @
0adf8caa
...
...
@@ -104,13 +104,14 @@ int MissionEditorController::addMissionItem(QGeoCoordinate coordinate)
qWarning
()
<<
"addMissionItem called with _canEdit == false"
;
}
// Coordinate will come through without altitude
coordinate
.
setAltitude
(
MissionItem
::
defaultAltitude
);
MissionItem
*
newItem
=
new
MissionItem
(
this
,
_missionItems
->
count
(),
coordinate
,
MAV_CMD_NAV_WAYPOINT
);
_initMissionItem
(
newItem
);
newItem
->
setAltitude
(
30
);
if
(
_missionItems
->
count
()
==
1
)
{
newItem
->
setCommand
(
MavlinkQmlSingleton
::
MAV_CMD_NAV_TAKEOFF
);
}
qDebug
()
<<
"MissionItem"
<<
newItem
->
coordinate
();
_missionItems
->
append
(
newItem
);
_recalcAll
();
...
...
src/MissionItem.cc
View file @
0adf8caa
...
...
@@ -36,6 +36,13 @@ This file is part of the QGROUNDCONTROL project
QGC_LOGGING_CATEGORY
(
MissionItemLog
,
"MissionItemLog"
)
const
double
MissionItem
::
defaultPitch
=
15.0
;
const
double
MissionItem
::
defaultHeading
=
0.0
;
const
double
MissionItem
::
defaultAltitude
=
25.0
;
const
double
MissionItem
::
defaultAcceptanceRadius
=
3.0
;
const
double
MissionItem
::
defaultLoiterOrbitRadius
=
10.0
;
const
double
MissionItem
::
defaultLoiterTurns
=
1.0
;
QDebug
operator
<<
(
QDebug
dbg
,
const
MissionItem
&
missionItem
)
{
QDebugStateSaver
saver
(
dbg
);
...
...
@@ -82,14 +89,14 @@ MissionItem::MissionItem(QObject* parent,
,
_autocontinue
(
autocontinue
)
,
_isCurrentItem
(
isCurrentItem
)
,
_reachedTime
(
0
)
,
_
yawRadian
sFact
(
NULL
)
,
_
headingDegree
sFact
(
NULL
)
,
_dirty
(
false
)
,
_homePositionSpecialCase
(
false
)
{
_latitudeFact
=
new
Fact
(
0
,
"Latitude:"
,
FactMetaData
::
valueTypeDouble
,
this
);
_longitudeFact
=
new
Fact
(
0
,
"Longitude:"
,
FactMetaData
::
valueTypeDouble
,
this
);
_altitudeFact
=
new
Fact
(
0
,
"Altitude:"
,
FactMetaData
::
valueTypeDouble
,
this
);
_
yawRadiansFact
=
new
Fact
(
0
,
"Heading:"
,
FactMetaData
::
valueTypeDouble
,
this
);
_
headingDegreesFact
=
new
Fact
(
0
,
"Heading:"
,
FactMetaData
::
valueTypeDouble
,
this
);
_loiterOrbitRadiusFact
=
new
Fact
(
0
,
"Radius:"
,
FactMetaData
::
valueTypeDouble
,
this
);
_param1Fact
=
new
Fact
(
0
,
QString
(),
FactMetaData
::
valueTypeDouble
,
this
);
_param2Fact
=
new
Fact
(
0
,
QString
(),
FactMetaData
::
valueTypeDouble
,
this
);
...
...
@@ -100,7 +107,7 @@ MissionItem::MissionItem(QObject* parent,
setCoordinate
(
coordinate
);
setParam1
(
param1
);
setParam2
(
param2
);
setYawRadians
(
param4
);
_
setYawRadians
(
param4
);
setLoiterOrbitRadius
(
param3
);
// FIXME: Need to fill out more meta data
...
...
@@ -114,8 +121,8 @@ MissionItem::MissionItem(QObject* parent,
FactMetaData
*
altitudeMetaData
=
new
FactMetaData
(
FactMetaData
::
valueTypeDouble
,
_altitudeFact
);
altitudeMetaData
->
setUnits
(
"meters"
);
FactMetaData
*
yawMetaData
=
new
FactMetaData
(
FactMetaData
::
valueTypeDouble
,
_yawRadian
sFact
);
yaw
MetaData
->
setUnits
(
"deg"
);
FactMetaData
*
headingMetaData
=
new
FactMetaData
(
FactMetaData
::
valueTypeDouble
,
_headingDegree
sFact
);
heading
MetaData
->
setUnits
(
"deg"
);
_pitchMetaData
=
new
FactMetaData
(
FactMetaData
::
valueTypeDouble
,
this
);
_pitchMetaData
->
setUnits
(
"deg"
);
...
...
@@ -147,23 +154,10 @@ MissionItem::MissionItem(QObject* parent,
_latitudeFact
->
setMetaData
(
latitudeMetaData
);
_longitudeFact
->
setMetaData
(
longitudeMetaData
);
_altitudeFact
->
setMetaData
(
altitudeMetaData
);
_
yawRadiansFact
->
setMetaData
(
yaw
MetaData
);
_
headingDegreesFact
->
setMetaData
(
heading
MetaData
);
_loiterOrbitRadiusFact
->
setMetaData
(
loiterOrbitRadiusMetaData
);
// Connect to valueChanged to track dirty state
connect
(
_latitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_longitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_altitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_yawRadiansFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_loiterOrbitRadiusFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_param1Fact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_param2Fact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_altitudeRelativeToHomeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
// Connect valueChanged signals so we can output coordinateChanged signal
connect
(
_latitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_coordinateFactChanged
);
connect
(
_longitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_coordinateFactChanged
);
connect
(
_altitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_coordinateFactChanged
);
_connectSignals
();
}
MissionItem
::
MissionItem
(
const
MissionItem
&
other
,
QObject
*
parent
)
...
...
@@ -172,7 +166,7 @@ MissionItem::MissionItem(const MissionItem& other, QObject* parent)
_latitudeFact
=
new
Fact
(
this
);
_longitudeFact
=
new
Fact
(
this
);
_altitudeFact
=
new
Fact
(
this
);
_
yawRadiansFact
=
new
Fact
(
this
);
_
headingDegreesFact
=
new
Fact
(
this
);
_loiterOrbitRadiusFact
=
new
Fact
(
this
);
_param1Fact
=
new
Fact
(
this
);
_param2Fact
=
new
Fact
(
this
);
...
...
@@ -188,28 +182,11 @@ MissionItem::MissionItem(const MissionItem& other, QObject* parent)
_jumpSequenceMetaData
=
new
FactMetaData
(
this
);
_jumpRepeatMetaData
=
new
FactMetaData
(
this
);
// Connect to valueChanged to track dirty state
connect
(
_latitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_longitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_altitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_yawRadiansFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_loiterOrbitRadiusFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_param1Fact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_param2Fact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_altitudeRelativeToHomeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
// Connect valueChanged signals so we can output coordinateChanged signal
connect
(
_latitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_coordinateFactChanged
);
connect
(
_longitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_coordinateFactChanged
);
connect
(
_altitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_coordinateFactChanged
);
_connectSignals
();
*
this
=
other
;
}
MissionItem
::~
MissionItem
()
{
}
const
MissionItem
&
MissionItem
::
operator
=
(
const
MissionItem
&
other
)
{
_sequenceNumber
=
other
.
_sequenceNumber
;
...
...
@@ -225,7 +202,7 @@ const MissionItem& MissionItem::operator=(const MissionItem& other)
*
_latitudeFact
=
*
other
.
_latitudeFact
;
*
_longitudeFact
=
*
other
.
_longitudeFact
;
*
_altitudeFact
=
*
other
.
_altitudeFact
;
*
_
yawRadiansFact
=
*
other
.
_yawRadian
sFact
;
*
_
headingDegreesFact
=
*
other
.
_headingDegree
sFact
;
*
_loiterOrbitRadiusFact
=
*
other
.
_loiterOrbitRadiusFact
;
*
_param1Fact
=
*
other
.
_param1Fact
;
*
_param2Fact
=
*
other
.
_param2Fact
;
...
...
@@ -242,6 +219,30 @@ const MissionItem& MissionItem::operator=(const MissionItem& other)
return
*
this
;
}
void
MissionItem
::
_connectSignals
(
void
)
{
// Connect to valueChanged to track dirty state
connect
(
_latitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_longitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_altitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_headingDegreesFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_loiterOrbitRadiusFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_param1Fact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_param2Fact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
connect
(
_altitudeRelativeToHomeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_factValueChanged
);
// Connect valueChanged signals so we can output coordinateChanged signal
connect
(
_latitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_coordinateFactChanged
);
connect
(
_longitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_coordinateFactChanged
);
connect
(
_altitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_coordinateFactChanged
);
connect
(
_headingDegreesFact
,
&
Fact
::
valueChanged
,
this
,
&
MissionItem
::
_headingDegreesFactChanged
);
}
MissionItem
::~
MissionItem
()
{
}
bool
MissionItem
::
isNavigationType
()
{
return
(
_command
<
MavlinkQmlSingleton
::
MAV_CMD_NAV_LAST
);
...
...
@@ -254,7 +255,7 @@ void MissionItem::save(QTextStream &saveStream)
position
=
position
.
arg
(
y
(),
0
,
'g'
,
18
);
position
=
position
.
arg
(
z
(),
0
,
'g'
,
18
);
QString
parameters
(
"%1
\t
%2
\t
%3
\t
%4"
);
parameters
=
parameters
.
arg
(
param1
(),
0
,
'g'
,
18
).
arg
(
param2
(),
0
,
'g'
,
18
).
arg
(
loiterOrbitRadius
(),
0
,
'g'
,
18
).
arg
(
yawRadians
(),
0
,
'g'
,
18
);
parameters
=
parameters
.
arg
(
param1
(),
0
,
'g'
,
18
).
arg
(
param2
(),
0
,
'g'
,
18
).
arg
(
loiterOrbitRadius
(),
0
,
'g'
,
18
).
arg
(
_
yawRadians
(),
0
,
'g'
,
18
);
// 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
<<
this
->
sequenceNumber
()
<<
"
\t
"
<<
this
->
isCurrentItem
()
<<
"
\t
"
<<
this
->
frame
()
<<
"
\t
"
<<
this
->
command
()
<<
"
\t
"
<<
parameters
<<
"
\t
"
<<
position
<<
"
\t
"
<<
this
->
autoContinue
()
<<
"
\r\n
"
;
//"\t" << this->getDescription() << "\r\n";
...
...
@@ -271,7 +272,7 @@ bool MissionItem::load(QTextStream &loadStream)
setParam1
(
wpParams
[
4
].
toDouble
());
setParam2
(
wpParams
[
5
].
toDouble
());
setLoiterOrbitRadius
(
wpParams
[
6
].
toDouble
());
setYawRadians
(
wpParams
[
7
].
toDouble
());
_
setYawRadians
(
wpParams
[
7
].
toDouble
());
setLatitude
(
wpParams
[
8
].
toDouble
());
setLongitude
(
wpParams
[
9
].
toDouble
());
setAltitude
(
wpParams
[
10
].
toDouble
());
...
...
@@ -351,10 +352,26 @@ void MissionItem::setAction(int /*MAV_CMD*/ action)
// Fix defaults according to WP type
if
(
_command
==
MavlinkQmlSingleton
::
MAV_CMD_NAV_TAKEOFF
)
{
// We default to 15 degrees minimum takeoff pitch
setParam1
(
15.0
);
switch
(
_command
)
{
case
MavlinkQmlSingleton
:
:
MAV_CMD_NAV_TAKEOFF
:
setParam1
(
defaultPitch
);
break
;
case
MavlinkQmlSingleton
:
:
MAV_CMD_NAV_WAYPOINT
:
setAcceptanceRadius
(
defaultAcceptanceRadius
);
break
;
case
MavlinkQmlSingleton
:
:
MAV_CMD_NAV_LOITER_UNLIM
:
case
MavlinkQmlSingleton
:
:
MAV_CMD_NAV_LOITER_TIME
:
setLoiterOrbitRadius
(
defaultLoiterOrbitRadius
);
break
;
case
MavlinkQmlSingleton
:
:
MAV_CMD_NAV_LOITER_TURNS
:
setLoiterOrbitRadius
(
defaultLoiterOrbitRadius
);
setParam1
(
defaultLoiterTurns
);
break
;
default:
break
;
}
setHeadingDegrees
(
defaultHeading
);
setAltitude
(
defaultAltitude
);
if
(
specifiesCoordinate
())
{
if
(
_frame
!=
MAV_FRAME_GLOBAL
&&
_frame
!=
MAV_FRAME_GLOBAL_RELATIVE_ALT
)
{
...
...
@@ -438,7 +455,7 @@ void MissionItem::setParam3(double param3)
void
MissionItem
::
setParam4
(
double
param4
)
{
setYawRadians
(
param4
);
_
setYawRadians
(
param4
);
}
void
MissionItem
::
setParam5
(
double
param5
)
...
...
@@ -526,6 +543,46 @@ QString MissionItem::commandName(void)
return
type
;
}
QString
MissionItem
::
commandDescription
(
void
)
{
QString
description
;
switch
(
_command
)
{
case
MAV_CMD_NAV_WAYPOINT
:
description
=
"Travel to a position in 3D space."
;
break
;
case
MAV_CMD_NAV_LOITER_UNLIM
:
description
=
"Travel to a position and Loiter around the specified radius indefinitely."
;
break
;
case
MAV_CMD_NAV_LOITER_TURNS
:
description
=
"Travel to a position and Loiter around the specified radius for a number of turns."
;
break
;
case
MAV_CMD_NAV_LOITER_TIME
:
description
=
"Travel to a position and Loiter around the specified radius for an amount of time."
;
break
;
case
MAV_CMD_NAV_RETURN_TO_LAUNCH
:
description
=
"Send the vehicle back to the home position set when armed."
;
break
;
case
MAV_CMD_NAV_LAND
:
description
=
"Land vehicle at the current location."
;
break
;
case
MAV_CMD_NAV_TAKEOFF
:
description
=
"Lift off from the ground and travel to the specified position."
;
break
;
case
MAV_CMD_CONDITION_DELAY
:
description
=
"Delay"
;
break
;
case
MAV_CMD_DO_JUMP
:
description
=
"Jump To Command"
;
break
;
default:
description
=
QString
(
"Unknown (%1)"
).
arg
(
_command
);
break
;
}
return
description
;
}
QStringList
MissionItem
::
valueLabels
(
void
)
{
QStringList
labels
;
...
...
@@ -590,24 +647,24 @@ QStringList MissionItem::valueStrings(void)
switch
(
_command
)
{
case
MAV_CMD_NAV_WAYPOINT
:
list
<<
_oneDecimalString
(
_altitudeFact
->
value
().
toDouble
())
<<
_oneDecimalString
(
yaw
Degrees
())
<<
_oneDecimalString
(
param2
())
<<
_oneDecimalString
(
param1
());
list
<<
_oneDecimalString
(
_altitudeFact
->
value
().
toDouble
())
<<
_oneDecimalString
(
heading
Degrees
())
<<
_oneDecimalString
(
param2
())
<<
_oneDecimalString
(
param1
());
break
;
case
MAV_CMD_NAV_LOITER_UNLIM
:
list
<<
_oneDecimalString
(
yawRadians
()
*
(
180.0
/
M_PI
))
<<
_oneDecimalString
(
loiterOrbitRadius
());
list
<<
_oneDecimalString
(
headingDegrees
(
))
<<
_oneDecimalString
(
loiterOrbitRadius
());
break
;
case
MAV_CMD_NAV_LOITER_TURNS
:
list
<<
_oneDecimalString
(
yawRadians
()
*
(
180.0
/
M_PI
))
<<
_oneDecimalString
(
loiterOrbitRadius
())
<<
_oneDecimalString
(
param1
());
list
<<
_oneDecimalString
(
headingDegrees
(
))
<<
_oneDecimalString
(
loiterOrbitRadius
())
<<
_oneDecimalString
(
param1
());
break
;
case
MAV_CMD_NAV_LOITER_TIME
:
list
<<
_oneDecimalString
(
yawRadians
()
*
(
180.0
/
M_PI
))
<<
_oneDecimalString
(
loiterOrbitRadius
())
<<
_oneDecimalString
(
param1
());
list
<<
_oneDecimalString
(
headingDegrees
(
))
<<
_oneDecimalString
(
loiterOrbitRadius
())
<<
_oneDecimalString
(
param1
());
break
;
case
MAV_CMD_NAV_RETURN_TO_LAUNCH
:
break
;
case
MAV_CMD_NAV_LAND
:
list
<<
_oneDecimalString
(
_altitudeFact
->
value
().
toDouble
())
<<
_oneDecimalString
(
yawRadians
()
*
(
180.0
/
M_PI
));
list
<<
_oneDecimalString
(
_altitudeFact
->
value
().
toDouble
())
<<
_oneDecimalString
(
headingDegrees
(
));
break
;
case
MAV_CMD_NAV_TAKEOFF
:
list
<<
_oneDecimalString
(
_altitudeFact
->
value
().
toDouble
())
<<
_oneDecimalString
(
yawRadians
()
*
(
180.0
/
M_PI
))
<<
_oneDecimalString
(
param1
());
list
<<
_oneDecimalString
(
_altitudeFact
->
value
().
toDouble
())
<<
_oneDecimalString
(
headingDegrees
(
))
<<
_oneDecimalString
(
param1
());
break
;
case
MAV_CMD_CONDITION_DELAY
:
list
<<
_oneDecimalString
(
param1
());
...
...
@@ -659,59 +716,38 @@ QmlObjectListModel* MissionItem::textFieldFacts(void)
switch
((
MAV_CMD
)
_command
)
{
case
MAV_CMD_NAV_WAYPOINT
:
_param2Fact
->
_setName
(
"Radius:"
);
_param2Fact
->
setMetaData
(
_acceptanceRadiusMetaData
);
_param1Fact
->
_setName
(
"Hold:"
);
_param1Fact
->
setMetaData
(
_holdTimeMetaData
);
model
->
append
(
_latitudeFact
);
model
->
append
(
_longitudeFact
);
model
->
append
(
_altitudeFact
);
if
(
!
_homePositionSpecialCase
)
{
model
->
append
(
_yawRadiansFact
);
model
->
append
(
_param2Fact
);
model
->
append
(
_param1Fact
);
}
break
;
case
MAV_CMD_NAV_LOITER_UNLIM
:
model
->
append
(
_latitudeFact
);
model
->
append
(
_longitudeFact
);
model
->
append
(
_altitudeFact
);
model
->
append
(
_yawRadiansFact
);
model
->
append
(
_loiterOrbitRadiusFact
);
break
;
case
MAV_CMD_NAV_LOITER_TURNS
:
_param1Fact
->
_setName
(
"Turns:"
);
_param1Fact
->
setMetaData
(
_loiterTurnsMetaData
);
model
->
append
(
_latitudeFact
);
model
->
append
(
_longitudeFact
);
model
->
append
(
_altitudeFact
);
model
->
append
(
_yawRadiansFact
);
model
->
append
(
_loiterOrbitRadiusFact
);
model
->
append
(
_param1Fact
);
break
;
case
MAV_CMD_NAV_LOITER_TIME
:
_param1Fact
->
_setName
(
"Seconds:"
);
_param1Fact
->
setMetaData
(
_loiterSecondsMetaData
);
model
->
append
(
_latitudeFact
);
model
->
append
(
_longitudeFact
);
model
->
append
(
_altitudeFact
);
model
->
append
(
_yawRadiansFact
);
model
->
append
(
_loiterOrbitRadiusFact
);
model
->
append
(
_param1Fact
);
break
;
case
MAV_CMD_NAV_LAND
:
model
->
append
(
_latitudeFact
);
model
->
append
(
_longitudeFact
);
model
->
append
(
_altitudeFact
);
model
->
append
(
_yawRadiansFact
);
break
;
case
MAV_CMD_NAV_TAKEOFF
:
_param1Fact
->
_setName
(
"Pitch:"
);
_param1Fact
->
setMetaData
(
_pitchMetaData
);
model
->
append
(
_latitudeFact
);
model
->
append
(
_longitudeFact
);
model
->
append
(
_altitudeFact
);
model
->
append
(
_yawRadiansFact
);
model
->
append
(
_param1Fact
);
break
;
case
MAV_CMD_CONDITION_DELAY
:
...
...
@@ -731,6 +767,11 @@ QmlObjectListModel* MissionItem::textFieldFacts(void)
break
;
}
if
(
specifiesHeading
())
{
model
->
append
(
_headingDegreesFact
);
}
return
model
;
}
...
...
@@ -768,30 +809,30 @@ QmlObjectListModel* MissionItem::checkboxFacts(void)
return
model
;
}
double
MissionItem
::
yawRadian
s
(
void
)
const
double
MissionItem
::
headingDegree
s
(
void
)
const
{
return
_
yawRadian
sFact
->
value
().
toDouble
();
return
_
headingDegree
sFact
->
value
().
toDouble
();
}
void
MissionItem
::
set
YawRadians
(
double
yaw
)
void
MissionItem
::
set
HeadingDegrees
(
double
headingDegrees
)
{
if
(
yawRadians
()
!=
yaw
)
{
_yawRadiansFact
->
setValue
(
yaw
);
if
(
_headingDegreesFact
->
value
().
toDouble
()
!=
headingDegrees
)
{
_headingDegreesFact
->
setValue
(
headingDegrees
);
emit
changed
(
this
);
emit
valueStringsChanged
(
valueStrings
());
emit
headingDegreesChanged
(
headingDegrees
);
}
}
double
MissionItem
::
yawDegree
s
(
void
)
const
double
MissionItem
::
_yawRadian
s
(
void
)
const
{
return
yawRadians
()
*
(
180.0
/
M_PI
);
return
_headingDegreesFact
->
value
().
toDouble
()
*
(
M_PI
/
180.0
);
}
void
MissionItem
::
setYawDegrees
(
double
yaw
)
void
MissionItem
::
_setYawRadians
(
double
yawRadians
)
{
set
YawRadians
(
yaw
*
(
M_PI
/
180.0
));
set
HeadingDegrees
(
yawRadians
*
(
180
/
M_PI
));
}
QGeoCoordinate
MissionItem
::
coordinate
(
void
)
const
...
...
@@ -854,3 +895,19 @@ void MissionItem::_coordinateFactChanged(QVariant value)
Q_UNUSED
(
value
);
emit
coordinateChanged
(
coordinate
());
}
bool
MissionItem
::
specifiesHeading
(
void
)
const
{
switch
((
MAV_CMD
)
_command
)
{
case
MAV_CMD_NAV_LAND
:
case
MAV_CMD_NAV_TAKEOFF
:
return
true
;
default:
return
false
;
}
}
void
MissionItem
::
_headingDegreesFactChanged
(
QVariant
value
)
{
emit
headingDegreesChanged
(
value
.
toDouble
());
}
src/MissionItem.h
View file @
0adf8caa
...
...
@@ -50,9 +50,9 @@ public:
QGeoCoordinate
coordiante
=
QGeoCoordinate
(),
int
action
=
MAV_CMD_NAV_WAYPOINT
,
double
param1
=
0
.
0
,
double
param2
=
0
.
0
,
double
param3
=
0
.
0
,
double
param4
=
0
.
0
,
double
param2
=
defaultAcceptanceRadius
,
double
param3
=
defaultLoiterOrbitRadius
,
double
param4
=
defaultHeading
,
bool
autocontinue
=
true
,
bool
isCurrentItem
=
false
,
int
frame
=
MAV_FRAME_GLOBAL_RELATIVE_ALT
);
...
...
@@ -67,10 +67,16 @@ public:
Q_PROPERTY
(
int
sequenceNumber
READ
sequenceNumber
WRITE
setSequenceNumber
NOTIFY
sequenceNumberChanged
)
Q_PROPERTY
(
bool
isCurrentItem
READ
isCurrentItem
WRITE
setIsCurrentItem
NOTIFY
isCurrentItemChanged
)
Q_PROPERTY
(
bool
specifiesCoordinate
READ
specifiesCoordinate
NOTIFY
commandChanged
)
Q_PROPERTY
(
QGeoCoordinate
coordinate
READ
coordinate
WRITE
setCoordinate
NOTIFY
coordinateChanged
)
Q_PROPERTY
(
bool
specifiesHeading
READ
specifiesHeading
NOTIFY
commandChanged
)
Q_PROPERTY
(
double
heading
READ
headingDegrees
WRITE
setHeadingDegrees
NOTIFY
headingDegreesChanged
)
Q_PROPERTY
(
QStringList
commandNames
READ
commandNames
CONSTANT
)
Q_PROPERTY
(
QString
commandName
READ
commandName
NOTIFY
commandChanged
)
Q_PROPERTY
(
QString
commandDescription
READ
commandDescription
NOTIFY
commandChanged
)
Q_PROPERTY
(
QStringList
valueLabels
READ
valueLabels
NOTIFY
commandChanged
)
Q_PROPERTY
(
QStringList
valueStrings
READ
valueStrings
NOTIFY
valueStringsChanged
)
Q_PROPERTY
(
int
commandByIndex
READ
commandByIndex
WRITE
setCommandByIndex
NOTIFY
commandChanged
)
...
...
@@ -88,12 +94,16 @@ public:
void
setIsCurrentItem
(
bool
isCurrentItem
);
bool
specifiesCoordinate
(
void
)
const
;
QGeoCoordinate
coordinate
(
void
)
const
;
void
setCoordinate
(
const
QGeoCoordinate
&
coordinate
);
bool
specifiesHeading
(
void
)
const
;
double
headingDegrees
(
void
)
const
;
void
setHeadingDegrees
(
double
headingDegrees
);
QStringList
commandNames
(
void
);
QString
commandName
(
void
);
QString
commandDescription
(
void
);
int
commandByIndex
(
void
);
void
setCommandByIndex
(
int
index
);
...
...
@@ -107,9 +117,6 @@ public:
QmlObjectListModel
*
textFieldFacts
(
void
);
QmlObjectListModel
*
checkboxFacts
(
void
);
double
yawDegrees
(
void
)
const
;
void
setYawDegrees
(
double
yaw
);
bool
dirty
(
void
)
{
return
_dirty
;
}
void
setDirty
(
bool
dirty
);
...
...
@@ -136,9 +143,6 @@ public:
void
setY
(
double
y
);
void
setZ
(
double
z
);
double
yawRadians
(
void
)
const
;
void
setYawRadians
(
double
yaw
);
bool
autoContinue
()
const
{
return
_autocontinue
;
}
...
...
@@ -161,7 +165,7 @@ public:
return
loiterOrbitRadius
();
}
double
param4
()
const
{
return
yawRadians
();
return
_
yawRadians
();
}
double
param5
()
const
{
return
latitude
();
...
...
@@ -190,10 +194,18 @@ public:
void
setHomePositionSpecialCase
(
bool
homePositionSpecialCase
)
{
_homePositionSpecialCase
=
homePositionSpecialCase
;
}
static
const
double
defaultPitch
;
static
const
double
defaultHeading
;
static
const
double
defaultAltitude
;
static
const
double
defaultAcceptanceRadius
;
static
const
double
defaultLoiterOrbitRadius
;
static
const
double
defaultLoiterTurns
;
signals:
void
sequenceNumberChanged
(
int
sequenceNumber
);
void
isCurrentItemChanged
(
bool
isCurrentItem
);
void
coordinateChanged
(
const
QGeoCoordinate
&
coordinate
);
void
headingDegreesChanged
(
double
heading
);
void
dirtyChanged
(
bool
dirty
);
/** @brief Announces a change to the waypoint data */
...
...
@@ -234,9 +246,13 @@ public:
private
slots
:
void
_factValueChanged
(
QVariant
value
);
void
_coordinateFactChanged
(
QVariant
value
);
void
_headingDegreesFactChanged
(
QVariant
value
);
private:
QString
_oneDecimalString
(
double
value
);
void
_connectSignals
(
void
);
double
_yawRadians
(
void
)
const
;
void
_setYawRadians
(
double
yawRadians
);
private:
typedef
struct
{
...
...
@@ -254,7 +270,7 @@ private:
Fact
*
_latitudeFact
;
Fact
*
_longitudeFact
;
Fact
*
_altitudeFact
;
Fact
*
_
yawRadian
sFact
;
Fact
*
_
headingDegree
sFact
;
Fact
*
_loiterOrbitRadiusFact
;
Fact
*
_param1Fact
;
Fact
*
_param2Fact
;
...
...
src/QmlControls/DropButton.qml
View file @
0adf8caa
...
...
@@ -224,7 +224,7 @@ Item {
context
.
lineTo
(
dropItemHolderRect
.
x
,
dropItemHolderRect
.
y
)
context
.
closePath
()
context
.
fillStyle
=
qgcPal
.
button
context
.
fillStyle
=
qgcPal
.
windowShade
context
.
fill
()
}
}
// Canvas - arrowCanvas
...
...
src/QmlControls/MissionItemEditor.qml
View file @
0adf8caa
...
...
@@ -19,34 +19,26 @@ Rectangle {
signal
clicked
signal
remove
height
:
missionItem
.
isCurrentItem
?
(
missionItem
.
textFieldFacts
.
count
*
(
measureTextField
.
height
+
_margin
))
+
(
missionItem
.
checkboxFacts
.
count
*
(
measureCheckbox
.
height
+
_margin
))
+
commandPicker
.
height
+
(
deleteButton
.
visible
?
deleteButton
.
height
:
0
)
+
(
_margin
*
9
)
:
commandPicker
.
height
+
(
_margin
*
2
)
height
:
innerItem
.
height
+
(
_margin
*
2
)
color
:
missionItem
.
isCurrentItem
?
qgcPal
.
buttonHighlight
:
qgcPal
.
windowShade
radius
:
_radius
readonly
property
real
_editFieldWidth
:
ScreenTools
.
defaultFontPixelWidth
*
16
readonly
property
real
_margin
:
ScreenTools
.
defaultFontPixelWidth
/
3
readonly
property
real
_margin
:
ScreenTools
.
defaultFontPixelWidth
/
2
readonly
property
real
_radius
:
ScreenTools
.
defaultFontPixelWidth
/
2
QGCPalette
{
id
:
qgcPal
colorGroupEnabled
:
enabled
}
QGCTextField
{
id
:
measureTextField
visible
:
false
}
QGCCheckBox
{
id
:
measureCheckbox
visible
:
false
}
Item
{
id
:
innerItem
anchors.margins
:
_margin
anchors.fill
:
parent
anchors.top
:
parent
.
top
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
height
:
valuesRect
.
visible
?
valuesRect
.
y
+
valuesRect
.
height
:
valuesRect
.
y
MissionItemIndexLabel
{
id
:
label
...
...
@@ -69,7 +61,7 @@ Rectangle {
anchors.right
:
parent
.
right
currentIndex
:
missionItem
.
commandByIndex
model
:
missionItem
.
commandNames
visible
:
missionItem
.
sequenceNumber
!=
0
// Item 0 is home position, can't change item type
visible
:
missionItem
.
sequenceNumber
!=
0
&&
missionItem
.
isCurrentItem
onActivated
:
missionItem
.
commandByIndex
=
index
}
...
...
@@ -77,30 +69,36 @@ Rectangle {
Rectangle
{
anchors.fill
:
commandPicker
color
:
qgcPal
.
button
visible
:
missionItem
.
sequenceNumber
==
0
// Item 0 is home position, can't change item typ
e
visible
:
!
commandPicker
.
visibl
e
QGCLabel
{
id
:
homeLabel
anchors.leftMargin
:
ScreenTools
.
defaultFontPixelWidth
anchors.fill
:
parent
verticalAlignment
:
Text
.
AlignVCenter
text
:
"
Home
"
text
:
missionItem
.
sequenceNumber
==
0
?
"
Home
"
:
missionItem
.
commandName
color
:
qgcPal
.
buttonText
}
}
Rectangle
{
id
:
valuesRect
anchors.topMargin
:
_margin
anchors.top
:
commandPicker
.
bottom
anchors.bottom
:
parent
.
bottom
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
height
:
valuesItem
.
height
color
:
qgcPal
.
windowShadeDark
visible
:
missionItem
.
isCurrentItem
radius
:
_radius
Item
{
id
:
valuesItem
anchors.margins
:
_margin
anchors.fill
:
parent
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
anchors.top
:
parent
.
top
height
:
valuesColumn
.
height
+
_margin
Column
{
id
:
valuesColumn
...
...
@@ -109,6 +107,12 @@ Rectangle {
anchors.top
:
parent
.
top
spacing
:
_margin
QGCLabel
{
width
:
parent
.
width
wrapMode
:
Text
.
WordWrap
text
:
missionItem
.
commandDescription
}
Repeater
{
model
:
missionItem
.
textFieldFacts
...
...
@@ -140,11 +144,6 @@ Rectangle {
}
}
Item
{
width
:
10
height
:
missionItem
.
textFieldFacts
.
count
?
_margin
:
0
}
Repeater
{
model
:
missionItem
.
checkboxFacts
...
...
@@ -154,28 +153,6 @@ Rectangle {
fact
:
object
}
}
Item
{
width
:
10
height
:
missionItem
.
checkboxFacts
.
count
?
_margin
:
0
}
Row
{
width
:
parent
.
width
spacing
:
_margin
readonly
property
real
buttonWidth
:
(
width
-
(
_margin
*
2
))
/
3
QGCButton
{
id
:
deleteButton
width
:
parent
.
buttonWidth
text
:
"
Delete
"
visible
:
!
readOnly
onClicked
:
_root
.
remove
()
}
}
}
// Column
}
// Item
}
// Rectangle
...
...
src/QmlControls/MissionItemIndexLabel.qml
View file @
0adf8caa
...
...
@@ -13,7 +13,7 @@ Rectangle {
QGCPalette
{
id
:
qgcPal
}
width
:
ScreenTools
.
defaultFontPixelHeight
*
1.5
width
:
ScreenTools
.
mediumFontPixelSize
*
1.5
height
:
width
radius
:
width
/
2
border.width
:
2
...
...
@@ -32,5 +32,6 @@ Rectangle {
horizontalAlignment
:
Text
.
AlignHCenter
verticalAlignment
:
Text
.
AlignVCenter
color
:
"
white
"
font.pixelSize
:
ScreenTools
.
mediumFontPixelSize
}
}
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