diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index 319f391e999252fe6f2babc8bfd5586422cf79da..f89dcb2c91ff48d16ca6a8fe18040ee6ac85f987 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -81,6 +81,7 @@
src/PlanView/FWLandingPatternMapVisual.qml
src/PlanView/GeoFenceEditor.qml
src/PlanView/GeoFenceMapVisuals.qml
+ src/QmlControls/HeightIndicator.qml
src/QmlControls/IndicatorButton.qml
src/QmlControls/JoystickThumbPad.qml
src/QmlControls/LogReplayStatusBar.qml
diff --git a/src/PlanView/FWLandingPatternMapVisual.qml b/src/PlanView/FWLandingPatternMapVisual.qml
index 0c9e70e580bb2bd16d3e1c979a985def0a8844b1..fbb1a41e6e9a02a44ab9905420209ca25ce98351 100644
--- a/src/PlanView/FWLandingPatternMapVisual.qml
+++ b/src/PlanView/FWLandingPatternMapVisual.qml
@@ -11,6 +11,7 @@ import QtQuick 2.3
import QtQuick.Controls 1.2
import QtLocation 5.3
import QtPositioning 5.3
+import QtQuick.Layouts 1.11
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
@@ -29,13 +30,28 @@ Item {
readonly property real _landingWidthMeters: 15
readonly property real _landingLengthMeters: 100
- property var _missionItem: object
+ property var _missionItem: object
property var _mouseArea
- property var _dragAreas: [ ]
+ property var _dragAreas: [ ]
property var _flightPath
- property real _landingAreaBearing: _missionItem.landingCoordinate.azimuthTo(_missionItem.loiterTangentCoordinate)
+ property real _landingAreaBearing: _missionItem.landingCoordinate.azimuthTo(_missionItem.loiterTangentCoordinate)
property var _loiterPointObject
property var _landingPointObject
+ property real _transitionAltitudeMeters
+ property real _midSlopeAltitudeMeters
+ property real _landingAltitudeMeters: _missionItem.landingAltitude.rawValue
+ property real _loiterAltitudeMeters: _missionItem.loiterAltitude.rawValue
+
+ function _calcGlideSlopeHeights() {
+ var adjacent = _missionItem.landingCoordinate.distanceTo(_missionItem.loiterTangentCoordinate)
+ var opposite = _loiterAltitudeMeters - _landingAltitudeMeters
+ var angleRadians = Math.atan(opposite / adjacent)
+ var transitionDistance = _landingLengthMeters / 2
+ var glideSlopeDistance = adjacent - transitionDistance
+
+ _transitionAltitudeMeters = Math.tan(angleRadians) * (transitionDistance)
+ _midSlopeAltitudeMeters = Math.tan(angleRadians) * (transitionDistance + (glideSlopeDistance / 2))
+ }
function hideItemVisuals() {
objMgr.destroyObjects()
@@ -46,7 +62,9 @@ Item {
_loiterPointObject = objMgr.createObject(loiterPointComponent, map, true /* parentObjectIsMap */)
_landingPointObject = objMgr.createObject(landingPointComponent, map, true /* parentObjectIsMap */)
- var rgComponents = [ flightPathComponent, loiterRadiusComponent, landingAreaComponent, landingAreaLabelComponent, glideSlopeComponent, glideSlopeLabelComponent ]
+ var rgComponents = [ flightPathComponent, loiterRadiusComponent, landingAreaComponent, landingAreaLabelComponent,
+ glideSlopeComponent, glideSlopeLabelComponent, transitionHeightComponent, midGlideSlopeHeightComponent,
+ approachHeightComponent ]
objMgr.createObjects(rgComponents, map, true /* parentObjectIsMap */)
}
}
@@ -105,6 +123,9 @@ Item {
hideItemVisuals()
}
+ on_LandingAltitudeMetersChanged: _calcGlideSlopeHeights()
+ on_LoiterAltitudeMetersChanged: _calcGlideSlopeHeights()
+
Connections {
target: _missionItem
@@ -139,8 +160,15 @@ Item {
}
}
- onLandingCoordinateChanged: _setFlightPath()
- onLoiterTangentCoordinateChanged: _setFlightPath()
+ onLandingCoordinateChanged: {
+ _calcGlideSlopeHeights()
+ _setFlightPath()
+ }
+
+ onLoiterTangentCoordinateChanged: {
+ _calcGlideSlopeHeights()
+ _setFlightPath()
+ }
}
// Mouse area to capture landing point coordindate
@@ -295,7 +323,7 @@ Item {
id: glideSlopeLabelComponent
MapQuickItem {
- anchorPoint.x: 0
+ anchorPoint.x: sourceItem._rawBearing > 180 ? sourceItem.contentWidth : 0
anchorPoint.y: sourceItem.contentHeight / 2
z: QGroundControl.zOrderMapItems
visible: _missionItem.isCurrentItem
@@ -320,7 +348,7 @@ Item {
}
transform: Rotation {
- origin.x: 0
+ origin.x: sourceItem._rawBearing > 180 ? sourceItem.contentWidth : 0
origin.y: glideSlopeLabel.contentHeight / 2
angle: glideSlopeLabel._adjustedBearing
}
@@ -402,4 +430,84 @@ Item {
}
}
}
+
+ Component {
+ id: transitionHeightComponent
+
+ MapQuickItem {
+ anchorPoint.x: sourceItem.width / 2
+ anchorPoint.y: 0
+ z: QGroundControl.zOrderMapItems
+ visible: _missionItem.isCurrentItem
+
+ sourceItem: HeightIndicator {
+ heightText: QGroundControl.metersToAppSettingsDistanceUnits(_transitionAltitudeMeters).toFixed(1) + " " +
+ QGroundControl.appSettingsDistanceUnitsString
+ }
+
+ function recalc() {
+ var centeredCoordinate = _missionItem.landingCoordinate.atDistanceAndAzimuth(_landingLengthMeters / 2, _landingAreaBearing)
+ var angleIncrement = _landingAreaBearing > 180 ? -90 : 90
+ coordinate = centeredCoordinate.atDistanceAndAzimuth(_landingWidthMeters, _landingAreaBearing + angleIncrement)
+ }
+
+ Component.onCompleted: recalc()
+
+ Connections {
+ target: _missionItem
+ onLandingCoordinateChanged: recalc()
+ onLoiterTangentCoordinateChanged: recalc()
+ }
+
+ }
+ }
+
+ Component {
+ id: midGlideSlopeHeightComponent
+
+ MapQuickItem {
+ anchorPoint.x: sourceItem.width / 2
+ anchorPoint.y: 0
+ z: QGroundControl.zOrderMapItems
+ visible: _missionItem.isCurrentItem
+
+ sourceItem: HeightIndicator {
+ heightText: QGroundControl.metersToAppSettingsDistanceUnits(_midSlopeAltitudeMeters).toFixed(1) + " " +
+ QGroundControl.appSettingsDistanceUnitsString
+ }
+
+ function recalc() {
+ var transitionCoordinate = _missionItem.landingCoordinate.atDistanceAndAzimuth(_landingLengthMeters / 2, _landingAreaBearing)
+ var halfDistance = transitionCoordinate.distanceTo(_missionItem.loiterTangentCoordinate) / 2
+ var centeredCoordinate = transitionCoordinate.atDistanceAndAzimuth(halfDistance, _landingAreaBearing)
+ var angleIncrement = _landingAreaBearing > 180 ? -90 : 90
+ coordinate = centeredCoordinate.atDistanceAndAzimuth(_landingWidthMeters / 2, _landingAreaBearing + angleIncrement)
+ }
+
+ Component.onCompleted: recalc()
+
+ Connections {
+ target: _missionItem
+ onLandingCoordinateChanged: recalc()
+ onLoiterTangentCoordinateChanged: recalc()
+ }
+
+ }
+ }
+
+ Component {
+ id: approachHeightComponent
+
+ MapQuickItem {
+ anchorPoint.x: sourceItem.width / 2
+ anchorPoint.y: 0
+ z: QGroundControl.zOrderMapItems
+ visible: _missionItem.isCurrentItem
+ coordinate: _missionItem.loiterTangentCoordinate
+
+ sourceItem: HeightIndicator {
+ heightText: _missionItem.loiterAltitude.value.toFixed(1) + " " + QGroundControl.appSettingsDistanceUnitsString
+ }
+ }
+ }
}
diff --git a/src/QmlControls/HeightIndicator.qml b/src/QmlControls/HeightIndicator.qml
new file mode 100644
index 0000000000000000000000000000000000000000..ad86efe207efff4ee644d33d609b28fa5358a881
--- /dev/null
+++ b/src/QmlControls/HeightIndicator.qml
@@ -0,0 +1,46 @@
+import QtQuick 2.3
+import QtQuick.Controls 1.2
+import QtQuick.Layouts 1.11
+
+import QGroundControl.ScreenTools 1.0
+
+ColumnLayout {
+ spacing: 0
+
+ property color textColor: "white"
+ property string heightText: "30 ft"
+
+ Rectangle {
+ width: ScreenTools.defaultFontPixelWidth * 3
+ height: 1
+ color: textColor
+ Layout.alignment: Qt.AlignHCenter
+ }
+
+ Rectangle {
+ width: 1
+ height: ScreenTools.defaultFontPixelWidth * 1
+ color: textColor
+ Layout.alignment: Qt.AlignHCenter
+ }
+
+ QGCLabel {
+ text: heightText
+ color: textColor
+ Layout.alignment: Qt.AlignHCenter
+ }
+
+ Rectangle {
+ width: 1
+ height: ScreenTools.defaultFontPixelWidth * 1
+ color: textColor
+ Layout.alignment: Qt.AlignHCenter
+ }
+
+ Rectangle {
+ width: ScreenTools.defaultFontPixelWidth * 3
+ height: 1
+ color: textColor
+ Layout.alignment: Qt.AlignHCenter
+ }
+}
diff --git a/src/QmlControls/QGroundControl/Controls/qmldir b/src/QmlControls/QGroundControl/Controls/qmldir
index b18732f4c1f17df14add6e9258610fc0c43b57e6..b0e8cb7c7154eadd5eea21be4d2d8896dcd225b0 100644
--- a/src/QmlControls/QGroundControl/Controls/qmldir
+++ b/src/QmlControls/QGroundControl/Controls/qmldir
@@ -19,6 +19,7 @@ FlightModeMenu 1.0 FlightModeMenu.qml
GeoFenceEditor 1.0 GeoFenceEditor.qml
GeoFenceMapVisuals 1.0 GeoFenceMapVisuals.qml
HackFileDialog 1.0 HackFileDialog.qml
+HeightIndicator 1.0 HeightIndicator.qml
IndicatorButton 1.0 IndicatorButton.qml
JoystickThumbPad 1.0 JoystickThumbPad.qml
LogReplayStatusBar 1.0 LogReplayStatusBar.qml