Commit e3566933 authored by Don Gagne's avatar Don Gagne

Mission Settings replaces Planned Home Position

- Shot Interval in Survey
- Much change to time/distance calc
parent 63aecd5d
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
<file alias="MainWindowNative.qml">src/ui/MainWindowNative.qml</file> <file alias="MainWindowNative.qml">src/ui/MainWindowNative.qml</file>
<file alias="MavlinkSettings.qml">src/ui/preferences/MavlinkSettings.qml</file> <file alias="MavlinkSettings.qml">src/ui/preferences/MavlinkSettings.qml</file>
<file alias="MissionEditor.qml">src/MissionEditor/MissionEditor.qml</file> <file alias="MissionEditor.qml">src/MissionEditor/MissionEditor.qml</file>
<file alias="MissionSettingsEditor.qml">src/MissionEditor/MissionSettingsEditor.qml</file>
<file alias="MockLink.qml">src/ui/preferences/MockLink.qml</file> <file alias="MockLink.qml">src/ui/preferences/MockLink.qml</file>
<file alias="MockLinkSettings.qml">src/ui/preferences/MockLinkSettings.qml</file> <file alias="MockLinkSettings.qml">src/ui/preferences/MockLinkSettings.qml</file>
<file alias="MultiVehicleView.qml">src/MultiVehicle/MultiVehicleView.qml</file> <file alias="MultiVehicleView.qml">src/MultiVehicle/MultiVehicleView.qml</file>
......
...@@ -944,9 +944,8 @@ QGCView { ...@@ -944,9 +944,8 @@ QGCView {
missionItems: missionController.visualItems missionItems: missionController.visualItems
expandedWidth: missionItemEditor.x - (ScreenTools.defaultFontPixelWidth * 2) expandedWidth: missionItemEditor.x - (ScreenTools.defaultFontPixelWidth * 2)
missionDistance: missionController.missionDistance missionDistance: missionController.missionDistance
missionTime: missionController.missionTime
missionMaxTelemetry: missionController.missionMaxTelemetry missionMaxTelemetry: missionController.missionMaxTelemetry
cruiseDistance: missionController.cruiseDistance
hoverDistance: missionController.hoverDistance
visible: _editingLayer == _layerMission && !ScreenTools.isShortScreen visible: _editingLayer == _layerMission && !ScreenTools.isShortScreen
} }
} // FlightMap } // FlightMap
......
...@@ -26,8 +26,9 @@ Rectangle { ...@@ -26,8 +26,9 @@ Rectangle {
signal insert signal insert
signal moveHomeToMapCenter signal moveHomeToMapCenter
property bool _currentItem: missionItem.isCurrentItem property bool _currentItem: missionItem.isCurrentItem
property color _outerTextColor: _currentItem ? "black" : qgcPal.text property color _outerTextColor: _currentItem ? "black" : qgcPal.text
property bool _noMissionItemsAdded: ListView.view.model.count == 1
readonly property real _editFieldWidth: Math.min(width - _margin * 2, ScreenTools.defaultFontPixelWidth * 12) readonly property real _editFieldWidth: Math.min(width - _margin * 2, ScreenTools.defaultFontPixelWidth * 12)
readonly property real _margin: ScreenTools.defaultFontPixelWidth / 2 readonly property real _margin: ScreenTools.defaultFontPixelWidth / 2
...@@ -38,7 +39,6 @@ Rectangle { ...@@ -38,7 +39,6 @@ Rectangle {
colorGroupEnabled: enabled colorGroupEnabled: enabled
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
visible: !missionItem.isCurrentItem visible: !missionItem.isCurrentItem
...@@ -121,7 +121,6 @@ Rectangle { ...@@ -121,7 +121,6 @@ Rectangle {
anchors.rightMargin: ScreenTools.defaultFontPixelWidth anchors.rightMargin: ScreenTools.defaultFontPixelWidth
anchors.left: label.right anchors.left: label.right
anchors.top: parent.top anchors.top: parent.top
//anchors.right: hamburger.left
visible: missionItem.sequenceNumber != 0 && missionItem.isCurrentItem && !missionItem.rawEdit && missionItem.isSimpleItem visible: missionItem.sequenceNumber != 0 && missionItem.isCurrentItem && !missionItem.rawEdit && missionItem.isSimpleItem
text: missionItem.commandName text: missionItem.commandName
...@@ -133,7 +132,7 @@ Rectangle { ...@@ -133,7 +132,7 @@ Rectangle {
} }
} }
onClicked: qgcView.showDialog(commandDialog, qsTr("Select Mission Command"), qgcView.showDialogDefaultWidth, StandardButton.Cancel) onClicked: qgcView.showDialog(commandDialog, qsTr("Select Mission Command"), qgcView.showDialogDefaultWidth, StandardButton.Cancel)
} }
QGCLabel { QGCLabel {
...@@ -141,7 +140,7 @@ Rectangle { ...@@ -141,7 +140,7 @@ Rectangle {
visible: missionItem.sequenceNumber == 0 || !missionItem.isCurrentItem || !missionItem.isSimpleItem visible: missionItem.sequenceNumber == 0 || !missionItem.isCurrentItem || !missionItem.isSimpleItem
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
text: missionItem.sequenceNumber == 0 ? text: missionItem.sequenceNumber == 0 ?
qsTr("Planned Home Position") : qsTr("Mission Settings") :
(missionItem.isSimpleItem ? missionItem.commandName : qsTr("Survey")) (missionItem.isSimpleItem ? missionItem.commandName : qsTr("Survey"))
color: _outerTextColor color: _outerTextColor
} }
...@@ -153,8 +152,12 @@ Rectangle { ...@@ -153,8 +152,12 @@ Rectangle {
anchors.left: parent.left anchors.left: parent.left
anchors.top: commandPicker.bottom anchors.top: commandPicker.bottom
height: item ? item.height : 0 height: item ? item.height : 0
source: missionItem.isSimpleItem ? "qrc:/qml/SimpleItemEditor.qml" : "qrc:/qml/SurveyItemEditor.qml" source: missionItem.sequenceNumber == 0 ? "qrc:/qml/MissionSettingsEditor.qml" : (missionItem.isSimpleItem ? "qrc:/qml/SimpleItemEditor.qml" : "qrc:/qml/SurveyItemEditor.qml")
onLoaded: { item.visible = Qt.binding(function() { return _currentItem; }) }
onLoaded: {
item.visible = Qt.binding(function() { return _currentItem; })
}
property real availableWidth: _root.width - (_margin * 2) ///< How wide the editor should be property real availableWidth: _root.width - (_margin * 2) ///< How wide the editor should be
property var editorRoot: _root property var editorRoot: _root
} }
......
...@@ -20,20 +20,6 @@ import QGroundControl.FactSystem 1.0 ...@@ -20,20 +20,6 @@ import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0 import QGroundControl.FactControls 1.0
Rectangle { Rectangle {
readonly property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property Fact _offlineEditingVehicleType: QGroundControl.offlineEditingVehicleType
property Fact _offlineEditingCruiseSpeed: QGroundControl.offlineEditingCruiseSpeed
property Fact _offlineEditingHoverSpeed: QGroundControl.offlineEditingHoverSpeed
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 real missionDistance
property real missionMaxTelemetry
property real cruiseDistance
property real hoverDistance
width: _expanded ? expandedWidth : _collapsedWidth width: _expanded ? expandedWidth : _collapsedWidth
height: Math.max(valueGrid.height, valueMissionGrid.height) + (_margins * 2) height: Math.max(valueGrid.height, valueMissionGrid.height) + (_margins * 2)
radius: ScreenTools.defaultFontPixelWidth * 0.5 radius: ScreenTools.defaultFontPixelWidth * 0.5
...@@ -41,42 +27,35 @@ Rectangle { ...@@ -41,42 +27,35 @@ Rectangle {
opacity: 0.80 opacity: 0.80
clip: true clip: true
readonly property real margins: ScreenTools.defaultFontPixelWidth property var currentMissionItem ///< Mission item to display status for
property var missionItems ///< List of all available mission items
property real _collapsedWidth: valueGrid.width + (margins * 2) property real expandedWidth ///< Width of control when expanded
property bool _expanded: true property real missionDistance ///< Total mission distance
property real missionTime ///< Total mission time
property real _distance: _statusValid ? _currentMissionItem.distance : 0 property real missionMaxTelemetry
property real _altDifference: _statusValid ? _currentMissionItem.altDifference : 0
property real _gradient: _statusValid && _currentMissionItem.distance > 0 ? Math.atan(_currentMissionItem.altDifference / _currentMissionItem.distance) : 0 property real _collapsedWidth: valueGrid.width + (_margins * 2)
property real _gradientPercent: isNaN(_gradient) ? 0 : _gradient * 100 property bool _expanded: true
property real _azimuth: _statusValid ? _currentMissionItem.azimuth : -1
property real _missionDistance: _missionValid ? missionDistance : 0 property bool _statusValid: currentMissionItem != undefined
property real _missionMaxTelemetry: _missionValid ? missionMaxTelemetry : 0 property bool _missionValid: missionItems != undefined
property real _missionTime: _missionValid && _missionSpeed > 0 ? (_isVTOL ? _hoverTime + _cruiseTime : _missionDistance / _missionSpeed) : 0
property real _hoverDistance: _missionValid ? hoverDistance : 0 property real _distance: _statusValid ? _currentMissionItem.distance : NaN
property real _cruiseDistance: _missionValid ? cruiseDistance : 0 property real _altDifference: _statusValid ? _currentMissionItem.altDifference : NaN
property real _hoverTime: _missionValid && _offlineEditingHoverSpeed.value > 0 ? _hoverDistance / _offlineEditingHoverSpeed.value : 0 property real _gradient: _statusValid && _currentMissionItem.distance > 0 ? Math.atan(_currentMissionItem.altDifference / _currentMissionItem.distance) : NaN
property real _cruiseTime: _missionValid && _offlineEditingCruiseSpeed.value > 0 ? _cruiseDistance / _offlineEditingCruiseSpeed.value : 0 property real _gradientPercent: isNaN(_gradient) ? NaN : _gradient * 100
property real _azimuth: _statusValid ? _currentMissionItem.azimuth : NaN
property bool _statusValid: currentMissionItem != undefined property real _missionDistance: _missionValid ? missionDistance : NaN
property bool _vehicleValid: _activeVehicle != undefined property real _missionMaxTelemetry: _missionValid ? missionMaxTelemetry : NaN
property bool _missionValid: missionItems != undefined property real _missionTime: _missionValid ? missionTime : NaN
property bool _currentSurvey: _statusValid ? _currentMissionItem.commandName == "Survey" : false
property bool _isVTOL: _vehicleValid ? _activeVehicle.vtol : _offlineEditingVehicleType.enumStringValue == "VTOL" //hardcoded property string _distanceText: isNaN(_distance) ? "-.-" : QGroundControl.metersToAppSettingsDistanceUnits(_distance).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString
property real _missionSpeed: _offlineEditingVehicleType.enumStringValue == "Fixedwing" ? _offlineEditingCruiseSpeed.value : _offlineEditingHoverSpeed.value property string _altDifferenceText: isNaN(_altDifference) ? "-.-" : QGroundControl.metersToAppSettingsDistanceUnits(_altDifference).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString
property string _gradientText: isNaN(_gradient) ? "-.-" : _gradientPercent.toFixed(0) + "%"
property string _distanceText: _statusValid ? QGroundControl.metersToAppSettingsDistanceUnits(_distance).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString : " " property string _azimuthText: isNaN(_azimuth) ? "-.-" : Math.round(_azimuth)
property string _altText: _statusValid ? QGroundControl.metersToAppSettingsDistanceUnits(_altDifference).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString : " " property string _missionDistanceText: isNaN(_missionDistance) ? "-.-" : QGroundControl.metersToAppSettingsDistanceUnits(_missionDistance).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString
property string _gradientText: _statusValid ? _gradientPercent.toFixed(0) + "%" : " " property string _missionTimeText: isNaN(_missionTime) ? "-.-" : Number(_missionTime / 60).toFixed(1) + " min"
property string _azimuthText: _statusValid ? Math.round(_azimuth) : " " property string _missionMaxTelemetryText: isNaN(_missionMaxTelemetry) ? "-.-" : QGroundControl.metersToAppSettingsDistanceUnits(_missionMaxTelemetry).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString
property string _missionDistanceText: _missionValid ? QGroundControl.metersToAppSettingsDistanceUnits(_missionDistance).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString : " "
property string _missionTimeText: _missionValid ? Number(_missionTime / 60).toFixed(1) + " min" : " "
property string _missionMaxTelemetryText: _missionValid ? QGroundControl.metersToAppSettingsDistanceUnits(_missionMaxTelemetry).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString : " "
property string _hoverDistanceText: _missionValid ? QGroundControl.metersToAppSettingsDistanceUnits(_hoverDistance).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString : " "
property string _cruiseDistanceText: _missionValid ? QGroundControl.metersToAppSettingsDistanceUnits(_cruiseDistance).toFixed(2) + " " + QGroundControl.appSettingsDistanceUnitsString : " "
property string _hoverTimeText: _missionValid ? _hoverTime.toFixed(0) + "s" : " "
property string _cruiseTimeText: _missionValid ? _cruiseTime.toFixed(0) + "s" : " "
readonly property real _margins: ScreenTools.defaultFontPixelWidth readonly property real _margins: ScreenTools.defaultFontPixelWidth
...@@ -103,7 +82,7 @@ Rectangle { ...@@ -103,7 +82,7 @@ Rectangle {
QGCLabel { text: _distanceText } QGCLabel { text: _distanceText }
QGCLabel { text: qsTr("Alt diff:") } QGCLabel { text: qsTr("Alt diff:") }
QGCLabel { text: _altText } QGCLabel { text: _altDifferenceText }
QGCLabel { text: qsTr("Gradient:") } QGCLabel { text: qsTr("Gradient:") }
QGCLabel { text: _gradientText } QGCLabel { text: _gradientText }
...@@ -166,42 +145,6 @@ Rectangle { ...@@ -166,42 +145,6 @@ Rectangle {
QGCLabel { text: qsTr("Max telem dist:") } QGCLabel { text: qsTr("Max telem dist:") }
QGCLabel { text: _missionMaxTelemetryText } QGCLabel { text: _missionMaxTelemetryText }
QGCLabel {
text: qsTr("Hover distance:")
visible: _isVTOL
}
QGCLabel {
text: _hoverDistanceText
visible: _isVTOL
}
QGCLabel {
text: qsTr("Cruise distance:")
visible: _isVTOL
}
QGCLabel {
text: _cruiseDistanceText
visible: _isVTOL
}
QGCLabel {
text: qsTr("Hover time:")
visible: _isVTOL
}
QGCLabel {
text: _hoverTimeText
visible: _isVTOL
}
QGCLabel {
text: qsTr("Cruise time:")
visible: _isVTOL
}
QGCLabel {
text: _cruiseTimeText
visible: _isVTOL
}
} }
} }
} }
import QtQuick 2.5
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.2
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Vehicle 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Palette 1.0
// Editor for Mission Settings
Rectangle {
id: valuesRect
width: availableWidth
height: deferedload.status == Loader.Ready ? (visible ? deferedload.item.height : 0) : 0
color: qgcPal.windowShadeDark
visible: missionItem.isCurrentItem
radius: _radius
Loader {
id: deferedload
active: valuesRect.visible
asynchronous: true
anchors.margins: _margin
anchors.left: valuesRect.left
anchors.right: valuesRect.right
anchors.top: valuesRect.top
sourceComponent: Component {
Item {
id: valuesItem
height: valuesColumn.height + (_margin * 2)
property var _missionVehicle: missionController.vehicle
property bool _offlineEditing: _missionVehicle.isOfflineEditingVehicle
property bool _showOfflineEditingCombos: _offlineEditing && _noMissionItemsAdded
property bool _showCruiseSpeed: !_missionVehicle.multiRotor
property bool _showHoverSpeed: _missionVehicle.multiRotor || missionController.vehicle.vtol
readonly property string _firmwareLabel: qsTr("Firmware:")
readonly property string _vehicleLabel: qsTr("Vehicle:")
QGCPalette { id: qgcPal }
Column {
id: valuesColumn
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
spacing: _margin
QGCLabel { text: qsTr("Planned Home Position:") }
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: 1
color: qgcPal.text
}
Repeater {
model: missionItem.textFieldFacts
Item {
width: valuesColumn.width
height: textField.height
QGCLabel {
id: textFieldLabel
anchors.baseline: textField.baseline
text: object.name
}
FactTextField {
id: textField
anchors.right: parent.right
width: _editFieldWidth
showUnits: true
fact: object
visible: !_root.readOnly
}
FactLabel {
anchors.baseline: textFieldLabel.baseline
anchors.right: parent.right
fact: object
visible: _root.readOnly
}
}
}
QGCButton {
text: qsTr("Move Home to map center")
visible: missionItem.homePosition
onClicked: editorRoot.moveHomeToMapCenter()
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
width: parent.width
wrapMode: Text.WordWrap
font.pointSize: ScreenTools.smallFontPointSize
text: qsTr("Note: Planned home position for mission display only. Actual home position set by vehicle at flight time.")
}
QGCLabel { text: qsTr("Vehicle Info:") }
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: 1
color: qgcPal.text
}
GridLayout {
anchors.left: parent.left
anchors.right: parent.right
columnSpacing: ScreenTools.defaultFontPixelWidth
rowSpacing: columnSpacing
columns: 2
QGCLabel {
text: _firmwareLabel
visible: _showOfflineEditingCombos
}
FactComboBox {
Layout.fillWidth: true
fact: QGroundControl.offlineEditingFirmwareType
indexModel: false
visible: _showOfflineEditingCombos
}
QGCLabel {
text: _firmwareLabel
visible: !_showOfflineEditingCombos
}
QGCLabel {
text: _missionVehicle.firmwareTypeString
visible: !_showOfflineEditingCombos
}
QGCLabel {
text: _vehicleLabel
visible: _showOfflineEditingCombos
}
FactComboBox {
id: offlineVehicleCombo
Layout.fillWidth: true
fact: QGroundControl.offlineEditingVehicleType
indexModel: false
visible: _showOfflineEditingCombos
}
QGCLabel {
text: _vehicleLabel
visible: !_showOfflineEditingCombos
}
QGCLabel {
text: _missionVehicle.vehicleTypeString
visible: !_showOfflineEditingCombos
}
QGCLabel {
Layout.row: 2
text: qsTr("Cruise speed:")
visible: _showCruiseSpeed
}
FactTextField {
Layout.fillWidth: true
fact: QGroundControl.offlineEditingCruiseSpeed
visible: _showCruiseSpeed
}
QGCLabel {
Layout.row: 3
text: qsTr("Hover speed:")
visible: _showHoverSpeed
}
FactTextField {
Layout.fillWidth: true
fact: QGroundControl.offlineEditingHoverSpeed
visible: _showHoverSpeed
}
} // GridLayout
QGCLabel {
width: parent.width
wrapMode: Text.WordWrap
font.pointSize: ScreenTools.smallFontPointSize
text: qsTr("Note: Speeds are planned speeds only for time calculations. Actual vehicle will not be affected.")
}
} // Column
} // Item
} // Component
} // Loader
} // Rectangle
...@@ -579,14 +579,17 @@ Rectangle { ...@@ -579,14 +579,17 @@ Rectangle {
} }
Grid { Grid {
columns: 2 columns: 2
spacing: ScreenTools.defaultFontPixelWidth columnSpacing: ScreenTools.defaultFontPixelWidth
QGCLabel { text: qsTr("Survey area:") } QGCLabel { text: qsTr("Survey area:") }
QGCLabel { text: QGroundControl.squareMetersToAppSettingsAreaUnits(missionItem.coveredArea).toFixed(2) + " " + QGroundControl.appSettingsAreaUnitsString } QGCLabel { text: QGroundControl.squareMetersToAppSettingsAreaUnits(missionItem.coveredArea).toFixed(2) + " " + QGroundControl.appSettingsAreaUnitsString }
QGCLabel { text: qsTr("# shots:") } QGCLabel { text: qsTr("# shots:") }
QGCLabel { text: missionItem.cameraShots } QGCLabel { text: missionItem.cameraShots }
QGCLabel { text: qsTr("Shot interval:") }
QGCLabel { text: missionItem.timeBetweenShots.toFixed(1) + " " + qsTr("secs")}
} }
} }
} }
...@@ -46,6 +46,9 @@ public: ...@@ -46,6 +46,9 @@ public:
/// @return the greatest distance from any point of the complex item to some coordinate /// @return the greatest distance from any point of the complex item to some coordinate
virtual double greatestDistanceTo(const QGeoCoordinate &other) const = 0; virtual double greatestDistanceTo(const QGeoCoordinate &other) const = 0;
/// Informs the complex item of the cruise speed it will fly at
virtual void setCruiseSpeed(double cruiseSpeed) = 0;
/// This mission item attribute specifies the type of the complex item. /// This mission item attribute specifies the type of the complex item.
static const char* jsonComplexItemTypeKey; static const char* jsonComplexItemTypeKey;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
"mavCmdInfo": [ "mavCmdInfo": [
{ {
"comment": "MAV_CMD_NAV_LAST: Used for fake home position waypoint", "comment": "MAV_CMD_NAV_LAST: Used for mission settings / planned home position waypoint",
"id": 95, "id": 95,
"rawName": "HomeRaw", "rawName": "HomeRaw",
"friendlyName": "Home Position", "friendlyName": "Home Position",
......
This diff is collapsed.
...@@ -34,15 +34,18 @@ public: ...@@ -34,15 +34,18 @@ public:
MissionController(QObject* parent = NULL); MissionController(QObject* parent = NULL);
~MissionController(); ~MissionController();
Q_PROPERTY(QGeoCoordinate plannedHomePosition READ plannedHomePosition NOTIFY plannedHomePositionChanged) Q_PROPERTY(QGeoCoordinate plannedHomePosition READ plannedHomePosition NOTIFY plannedHomePositionChanged)
Q_PROPERTY(QmlObjectListModel* visualItems READ visualItems NOTIFY visualItemsChanged) Q_PROPERTY(QmlObjectListModel* visualItems READ visualItems NOTIFY visualItemsChanged)
Q_PROPERTY(QmlObjectListModel* complexVisualItems READ complexVisualItems NOTIFY complexVisualItemsChanged) Q_PROPERTY(QmlObjectListModel* complexVisualItems READ complexVisualItems NOTIFY complexVisualItemsChanged)
Q_PROPERTY(QmlObjectListModel* waypointLines READ waypointLines NOTIFY waypointLinesChanged) Q_PROPERTY(QmlObjectListModel* waypointLines READ waypointLines NOTIFY waypointLinesChanged)
Q_PROPERTY(double missionDistance READ missionDistance NOTIFY missionDistanceChanged) Q_PROPERTY(double missionDistance READ missionDistance NOTIFY missionDistanceChanged)
Q_PROPERTY(double missionMaxTelemetry READ missionMaxTelemetry NOTIFY missionMaxTelemetryChanged) Q_PROPERTY(double missionTime READ missionTime NOTIFY missionTimeChanged)
Q_PROPERTY(double cruiseDistance READ cruiseDistance NOTIFY cruiseDistanceChanged) Q_PROPERTY(double missionHoverDistance READ missionHoverDistance NOTIFY missionHoverDistanceChanged)
Q_PROPERTY(double hoverDistance READ hoverDistance NOTIFY hoverDistanceChanged) Q_PROPERTY(double missionCruiseDistance READ missionCruiseDistance NOTIFY missionCruiseDistanceChanged)
Q_PROPERTY(double missionHoverTime READ missionHoverTime NOTIFY missionHoverTimeChanged)
Q_PROPERTY(double missionCruiseTime READ missionCruiseTime NOTIFY missionCruiseTimeChanged)
Q_PROPERTY(double missionMaxTelemetry READ missionMaxTelemetry NOTIFY missionMaxTelemetryChanged)
Q_INVOKABLE void removeMissionItem(int index); Q_INVOKABLE void removeMissionItem(int index);
...@@ -80,15 +83,14 @@ public: ...@@ -80,15 +83,14 @@ public:
QmlObjectListModel* waypointLines (void) { return &_waypointLines; } QmlObjectListModel* waypointLines (void) { return &_waypointLines; }
double missionDistance (void) const { return _missionDistance; } double missionDistance (void) const { return _missionDistance; }
double missionTime (void) const { return _missionTime; }
double missionHoverDistance (void) const { return _missionHoverDistance; }
double missionHoverTime (void) const { return _missionHoverTime; }
double missionCruiseDistance (void) const { return _missionCruiseDistance; }
double missionCruiseTime (void) const { return _missionCruiseTime; }
double missionMaxTelemetry (void) const { return _missionMaxTelemetry; } double missionMaxTelemetry (void) const { return _missionMaxTelemetry; }
double cruiseDistance (void) const { return _cruiseDistance; } double cruiseSpeed (void) const;
double hoverDistance (void) const { return _hoverDistance; } double hoverSpeed (void) const;
void setMissionDistance (double missionDistance );
void setMissionMaxTelemetry (double missionMaxTelemetry);
void setCruiseDistance (double cruiseDistance );
void setHoverDistance (double hoverDistance );
signals: signals:
void plannedHomePositionChanged(QGeoCoordinate plannedHomePosition); void plannedHomePositionChanged(QGeoCoordinate plannedHomePosition);
...@@ -97,9 +99,16 @@ signals: ...@@ -97,9 +99,16 @@ signals:
void waypointLinesChanged(void); void waypointLinesChanged(void);
void newItemsFromVehicle(void); void newItemsFromVehicle(void);
void missionDistanceChanged(double missionDistance); void missionDistanceChanged(double missionDistance);
void missionTimeChanged(void);
void missionHoverDistanceChanged(double missionHoverDistance);
void missionHoverTimeChanged(void);
void missionCruiseDistanceChanged(double missionCruiseDistance);
void missionCruiseTimeChanged(void);
void missionMaxTelemetryChanged(double missionMaxTelemetry); void missionMaxTelemetryChanged(double missionMaxTelemetry);
void cruiseDistanceChanged(double cruiseDistance); void cruiseDistanceChanged(double cruiseDistance);
void hoverDistanceChanged(double hoverDistance); void hoverDistanceChanged(double hoverDistance);
void cruiseSpeedChanged(double cruiseSpeed);
void hoverSpeedChanged(double hoverSpeed);
private slots: private slots:
void _newMissionItemsAvailableFromVehicle(); void _newMissionItemsAvailableFromVehicle();
...@@ -123,7 +132,7 @@ private: ...@@ -123,7 +132,7 @@ private:
void _deinitVisualItem(VisualMissionItem* item); void _deinitVisualItem(VisualMissionItem* item);
void _setupActiveVehicle(Vehicle* activeVehicle, bool forceLoadFromVehicle); void _setupActiveVehicle(Vehicle* activeVehicle, bool forceLoadFromVehicle);
static void _calcPrevWaypointValues(double homeAlt, VisualMissionItem* currentItem, VisualMissionItem* prevItem, double* azimuth, double* distance, double* altDifference); static void _calcPrevWaypointValues(double homeAlt, VisualMissionItem* currentItem, VisualMissionItem* prevItem, double* azimuth, double* distance, double* altDifference);
static void _calcHomeDist(VisualMissionItem* currentItem, VisualMissionItem* homeItem, double* distance); static double _calcDistanceToHome(VisualMissionItem* currentItem, VisualMissionItem* homeItem);
bool _findLastAltitude(double* lastAltitude, MAV_FRAME* frame); bool _findLastAltitude(double* lastAltitude, MAV_FRAME* frame);
bool _findLastAcceptanceRadius(double* lastAcceptanceRadius); bool _findLastAcceptanceRadius(double* lastAcceptanceRadius);
void _addPlannedHomePosition(QmlObjectListModel* visualItems, bool addToCenter); void _addPlannedHomePosition(QmlObjectListModel* visualItems, bool addToCenter);
...@@ -134,6 +143,13 @@ private: ...@@ -134,6 +143,13 @@ private:
bool _loadJsonMissionFileV2(const QJsonObject& json, QmlObjectListModel* visualItems, QmlObjectListModel* complexItems, QString& errorString); bool _loadJsonMissionFileV2(const QJsonObject& json, QmlObjectListModel* visualItems, QmlObjectListModel* complexItems, QString& errorString);
bool _loadTextMissionFile(QTextStream& stream, QmlObjectListModel* visualItems, QString& errorString); bool _loadTextMissionFile(QTextStream& stream, QmlObjectListModel* visualItems, QString& errorString);
int _nextSequenceNumber(void); int _nextSequenceNumber(void);
void _setMissionDistance(double missionDistance);
void _setMissionTime(double missionTime);
void _setMissionHoverDistance(double missionHoverDistance);
void _setMissionHoverTime(double missionHoverTime);
void _setMissionCruiseDistance(double missionCruiseDistance);
void _setMissionCruiseTime(double missionCruiseTime);
void _setMissionMaxTelemetry(double missionMaxTelemetry);
// Overrides from PlanElementController // Overrides from PlanElementController
void _activeVehicleBeingRemoved(void) final; void _activeVehicleBeingRemoved(void) final;
...@@ -148,13 +164,19 @@ private: ...@@ -148,13 +164,19 @@ private:
bool _missionItemsRequested; bool _missionItemsRequested;
bool _queuedSend; bool _queuedSend;
double _missionDistance; double _missionDistance;
double _missionTime;
double _missionHoverDistance;
double _missionHoverTime;
double _missionCruiseDistance;
double _missionCruiseTime;
double _missionMaxTelemetry; double _missionMaxTelemetry;
double _cruiseDistance;
double _hoverDistance;
static const char* _settingsGroup; static const char* _settingsGroup;
static const char* _jsonFileTypeValue; static const char* _jsonFileTypeValue;
static const char* _jsonFirmwareTypeKey; static const char* _jsonFirmwareTypeKey;
static const char* _jsonVehicleTypeKey;
static const char* _jsonCruiseSpeedKey;
static const char* _jsonHoverSpeedKey;
static const char* _jsonItemsKey; static const char* _jsonItemsKey;
static const char* _jsonPlannedHomePositionKey; static const char* _jsonPlannedHomePositionKey;
static const char* _jsonParamsKey; static const char* _jsonParamsKey;
......
...@@ -54,4 +54,6 @@ void PlanElementController::_activeVehicleChanged(Vehicle* activeVehicle) ...@@ -54,4 +54,6 @@ void PlanElementController::_activeVehicleChanged(Vehicle* activeVehicle)
// Whenever vehicle changes we need to update syncInProgress // Whenever vehicle changes we need to update syncInProgress
emit syncInProgressChanged(syncInProgress()); emit syncInProgressChanged(syncInProgress());
emit vehicleChanged(_activeVehicle);
} }
...@@ -35,6 +35,8 @@ public: ...@@ -35,6 +35,8 @@ public:
Q_PROPERTY(QString fileExtension READ fileExtension CONSTANT) Q_PROPERTY(QString fileExtension READ fileExtension CONSTANT)
virtual QString fileExtension(void) const = 0; virtual QString fileExtension(void) const = 0;
Q_PROPERTY(Vehicle* vehicle READ vehicle NOTIFY vehicleChanged)
/// Should be called immediately upon Component.onCompleted. /// Should be called immediately upon Component.onCompleted.
/// @param editMode true: controller being used in Plan view, false: controller being used in Fly view /// @param editMode true: controller being used in Plan view, false: controller being used in Fly view
Q_INVOKABLE virtual void start(bool editMode); Q_INVOKABLE virtual void start(bool editMode);
...@@ -55,9 +57,12 @@ public: ...@@ -55,9 +57,12 @@ public:
virtual bool dirty (void) const = 0; virtual bool dirty (void) const = 0;
virtual void setDirty (bool dirty) = 0; virtual void setDirty (bool dirty) = 0;
Vehicle* vehicle(void) { return _activeVehicle; }
signals: signals:
void syncInProgressChanged (bool syncInProgress); void syncInProgressChanged (bool syncInProgress);
void dirtyChanged (bool dirty); void dirtyChanged (bool dirty);
void vehicleChanged (Vehicle* vehicle);
protected: protected:
MultiVehicleManager* _multiVehicleMgr; MultiVehicleManager* _multiVehicleMgr;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "JsonHelper.h" #include "JsonHelper.h"
#include "MissionController.h" #include "MissionController.h"
#include "QGCGeo.h" #include "QGCGeo.h"
#include "QGroundControlQmlGlobal.h"
#include <QPolygonF> #include <QPolygonF>
...@@ -70,6 +71,7 @@ SurveyMissionItem::SurveyMissionItem(Vehicle* vehicle, QObject* parent) ...@@ -70,6 +71,7 @@ SurveyMissionItem::SurveyMissionItem(Vehicle* vehicle, QObject* parent)
, _surveyDistance(0.0) , _surveyDistance(0.0)
, _cameraShots(0) , _cameraShots(0)
, _coveredArea(0.0) , _coveredArea(0.0)
, _timeBetweenShots(0.0)
, _gridAltitudeFact (0, _gridAltitudeFactName, FactMetaData::valueTypeDouble) , _gridAltitudeFact (0, _gridAltitudeFactName, FactMetaData::valueTypeDouble)
, _gridAngleFact (0, _gridAngleFactName, FactMetaData::valueTypeDouble) , _gridAngleFact (0, _gridAngleFactName, FactMetaData::valueTypeDouble)
, _gridSpacingFact (0, _gridSpacingFactName, FactMetaData::valueTypeDouble) , _gridSpacingFact (0, _gridSpacingFactName, FactMetaData::valueTypeDouble)
...@@ -132,7 +134,11 @@ SurveyMissionItem::SurveyMissionItem(Vehicle* vehicle, QObject* parent) ...@@ -132,7 +134,11 @@ SurveyMissionItem::SurveyMissionItem(Vehicle* vehicle, QObject* parent)
connect(&_cameraResolutionHeightFact, &Fact::valueChanged, this, &SurveyMissionItem::_cameraValueChanged); connect(&_cameraResolutionHeightFact, &Fact::valueChanged, this, &SurveyMissionItem::_cameraValueChanged);
connect(&_cameraFocalLengthFact, &Fact::valueChanged, this, &SurveyMissionItem::_cameraValueChanged); connect(&_cameraFocalLengthFact, &Fact::valueChanged, this, &SurveyMissionItem::_cameraValueChanged);
connect(this, &SurveyMissionItem::cameraTriggerChanged, this, &SurveyMissionItem::_cameraTriggerChanged); connect(this, &SurveyMissionItem::cameraTriggerChanged, this, &SurveyMissionItem::_cameraTriggerChanged);
connect(&_cameraTriggerDistanceFact, &Fact::valueChanged, this, &SurveyMissionItem::timeBetweenShotsChanged);
connect(_vehicle, &Vehicle::cruiseSpeedChanged, this, &SurveyMissionItem::timeBetweenShotsChanged);
connect(_vehicle, &Vehicle::hoverSpeedChanged, this, &SurveyMissionItem::timeBetweenShotsChanged);
} }
void SurveyMissionItem::_setSurveyDistance(double surveyDistance) void SurveyMissionItem::_setSurveyDistance(double surveyDistance)
...@@ -780,6 +786,7 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const ...@@ -780,6 +786,7 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const
pMissionItems->append(item); pMissionItems->append(item);
if (_cameraTrigger && i == 0) { if (_cameraTrigger && i == 0) {
// Turn on camera
MissionItem* item = new MissionItem(seqNum++, // sequence number MissionItem* item = new MissionItem(seqNum++, // sequence number
MAV_CMD_DO_SET_CAM_TRIGG_DIST, // MAV_CMD MAV_CMD_DO_SET_CAM_TRIGG_DIST, // MAV_CMD
MAV_FRAME_MISSION, // MAV_FRAME MAV_FRAME_MISSION, // MAV_FRAME
...@@ -793,6 +800,7 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const ...@@ -793,6 +800,7 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const
} }
if (_cameraTrigger) { if (_cameraTrigger) {
// Turn off camera
MissionItem* item = new MissionItem(seqNum++, // sequence number MissionItem* item = new MissionItem(seqNum++, // sequence number
MAV_CMD_DO_SET_CAM_TRIGG_DIST, // MAV_CMD MAV_CMD_DO_SET_CAM_TRIGG_DIST, // MAV_CMD
MAV_FRAME_MISSION, // MAV_FRAME MAV_FRAME_MISSION, // MAV_FRAME
...@@ -810,10 +818,9 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const ...@@ -810,10 +818,9 @@ QmlObjectListModel* SurveyMissionItem::getMissionItems(void) const
void SurveyMissionItem::_cameraTriggerChanged(void) void SurveyMissionItem::_cameraTriggerChanged(void)
{ {
setDirty(true); setDirty(true);
if (_gridPoints.count()) { // Camera trigger adds items
// If we have grid turn on/off camera trigger will add/remove two camera trigger mission items emit lastSequenceNumberChanged(lastSequenceNumber());
emit lastSequenceNumberChanged(lastSequenceNumber()); // We now have camera shot count
}
emit cameraShotsChanged(cameraShots()); emit cameraShotsChanged(cameraShots());
} }
...@@ -826,3 +833,16 @@ void SurveyMissionItem::_cameraValueChanged(void) ...@@ -826,3 +833,16 @@ void SurveyMissionItem::_cameraValueChanged(void)
{ {
emit cameraValueChanged(); emit cameraValueChanged();
} }
double SurveyMissionItem::timeBetweenShots(void) const
{
return _cruiseSpeed == 0 ? 0 : _cameraTriggerDistanceFact.rawValue().toDouble() / _cruiseSpeed;
}
void SurveyMissionItem::setCruiseSpeed(double cruiseSpeed)
{
if (!qFuzzyCompare(_cruiseSpeed, cruiseSpeed)) {
_cruiseSpeed = cruiseSpeed;
emit timeBetweenShotsChanged();
}
}
...@@ -48,6 +48,7 @@ public: ...@@ -48,6 +48,7 @@ public:
Q_PROPERTY(bool cameraOrientationLandscape MEMBER _cameraOrientationLandscape NOTIFY cameraOrientationLandscapeChanged) Q_PROPERTY(bool cameraOrientationLandscape MEMBER _cameraOrientationLandscape NOTIFY cameraOrientationLandscapeChanged)
Q_PROPERTY(bool manualGrid MEMBER _manualGrid NOTIFY manualGridChanged) Q_PROPERTY(bool manualGrid MEMBER _manualGrid NOTIFY manualGridChanged)
Q_PROPERTY(QString camera MEMBER _camera NOTIFY cameraChanged) Q_PROPERTY(QString camera MEMBER _camera NOTIFY cameraChanged)
Q_PROPERTY(double timeBetweenShots READ timeBetweenShots NOTIFY timeBetweenShotsChanged)
Q_INVOKABLE void clearPolygon(void); Q_INVOKABLE void clearPolygon(void);
Q_INVOKABLE void addPolygonCoordinate(const QGeoCoordinate coordinate); Q_INVOKABLE void addPolygonCoordinate(const QGeoCoordinate coordinate);
...@@ -72,6 +73,7 @@ public: ...@@ -72,6 +73,7 @@ public:
int cameraShots(void) const; int cameraShots(void) const;
double coveredArea(void) const { return _coveredArea; } double coveredArea(void) const { return _coveredArea; }
double timeBetweenShots(void) const;
// Overrides from ComplexMissionItem // Overrides from ComplexMissionItem
...@@ -80,6 +82,8 @@ public: ...@@ -80,6 +82,8 @@ public:
QmlObjectListModel* getMissionItems (void) const final; QmlObjectListModel* getMissionItems (void) const final;
bool load (const QJsonObject& complexObject, int sequenceNumber, QString& errorString) final; bool load (const QJsonObject& complexObject, int sequenceNumber, QString& errorString) final;
double greatestDistanceTo (const QGeoCoordinate &other) const final; double greatestDistanceTo (const QGeoCoordinate &other) const final;
void setCruiseSpeed (double cruiseSpeed) final;
// Overrides from VisualMissionItem // Overrides from VisualMissionItem
...@@ -121,6 +125,7 @@ signals: ...@@ -121,6 +125,7 @@ signals:
void cameraOrientationLandscapeChanged (bool cameraOrientationLandscape); void cameraOrientationLandscapeChanged (bool cameraOrientationLandscape);
void cameraChanged (QString camera); void cameraChanged (QString camera);
void manualGridChanged (bool manualGrid); void manualGridChanged (bool manualGrid);
void timeBetweenShotsChanged (void);
private slots: private slots:
void _cameraTriggerChanged(void); void _cameraTriggerChanged(void);
...@@ -158,6 +163,8 @@ private: ...@@ -158,6 +163,8 @@ private:
double _surveyDistance; double _surveyDistance;
int _cameraShots; int _cameraShots;
double _coveredArea; double _coveredArea;
double _timeBetweenShots;
double _cruiseSpeed;
Fact _gridAltitudeFact; Fact _gridAltitudeFact;
Fact _gridAngleFact; Fact _gridAngleFact;
...@@ -198,7 +205,6 @@ private: ...@@ -198,7 +205,6 @@ private:
static const char* _jsonCameraOrientationLandscapeKey; static const char* _jsonCameraOrientationLandscapeKey;
static const char* _jsonFixedValueIsAltitudeKey; static const char* _jsonFixedValueIsAltitudeKey;
static const char* _gridAltitudeFactName; static const char* _gridAltitudeFactName;
static const char* _gridAngleFactName; static const char* _gridAngleFactName;
static const char* _gridSpacingFactName; static const char* _gridSpacingFactName;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"name": "OfflineEditingFirmwareType", "name": "OfflineEditingFirmwareType",
"shortDescription": "Offline editing firmware type", "shortDescription": "Offline editing firmware type",
"type": "uint32", "type": "uint32",
"enumStrings": "ArduPilot Firmware,PX4 Pro Firmware,Mavlink Generic Firmware", "enumStrings": "ArduPilot,PX4 Pro,Mavlink Generic",
"enumValues": "3,12,0", "enumValues": "3,12,0",
"defaultValue": 3 "defaultValue": 3
}, },
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
"name": "OfflineEditingVehicleType", "name": "OfflineEditingVehicleType",
"shortDescription": "Offline editing vehicle type", "shortDescription": "Offline editing vehicle type",
"type": "uint32", "type": "uint32",
"enumStrings": "Fixedwing,Multicopter,VTOL,Rover,Sub", "enumStrings": "Fixed Wing,Multi-Rotor,VTOL,Rover,Sub",
"enumValues": "1,2,19,10,12", "enumValues": "1,2,19,10,12",
"defaultValue": 1 "defaultValue": 1
}, },
......
This diff is collapsed.
This diff is collapsed.
...@@ -13,6 +13,7 @@ import QtQuick.Controls 1.2 ...@@ -13,6 +13,7 @@ import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2 import QtQuick.Controls.Styles 1.2
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs 1.1
import QtMultimedia 5.5 import QtMultimedia 5.5
import QtQuick.Layouts 1.2
import QGroundControl 1.0 import QGroundControl 1.0
import QGroundControl.FactSystem 1.0 import QGroundControl.FactSystem 1.0
...@@ -33,6 +34,10 @@ QGCView { ...@@ -33,6 +34,10 @@ QGCView {
property Fact _percentRemainingAnnounce: QGroundControl.batteryPercentRemainingAnnounce property Fact _percentRemainingAnnounce: QGroundControl.batteryPercentRemainingAnnounce
property real _labelWidth: ScreenTools.defaultFontPixelWidth * 15 property real _labelWidth: ScreenTools.defaultFontPixelWidth * 15
property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30 property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30
property bool _showCruiseSpeed: offlineVehicleCombo.currentText != "Multicopter"
property bool _showHoverSpeed: offlineVehicleCombo.currentText != "FixedWing"
readonly property string _requiresRestart: qsTr("(Requires Restart)")
QGCPalette { id: qgcPal } QGCPalette { id: qgcPal }
...@@ -117,90 +122,6 @@ QGCView { ...@@ -117,90 +122,6 @@ QGCView {
} }
} }
//----------------------------------------------------------------- //-----------------------------------------------------------------
//-- Offline mission editing
Item {
width: qgcView.width * 0.8
height: offlineLabel.height
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
id: offlineLabel
text: qsTr("Offline Mission Editing (Requires Restart)")
font.family: ScreenTools.demiboldFontFamily
}
}
Rectangle {
height: offlineCol.height + (ScreenTools.defaultFontPixelHeight * 2)
width: qgcView.width * 0.8
color: qgcPal.windowShade
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
Column {
id: offlineCol
spacing: ScreenTools.defaultFontPixelWidth
anchors.centerIn: parent
Row {
spacing: ScreenTools.defaultFontPixelWidth
QGCLabel {
text: qsTr("Firmware:")
width: _labelWidth
anchors.baseline: offlineTypeCombo.baseline
}
FactComboBox {
id: offlineTypeCombo
width: _editFieldWidth
fact: QGroundControl.offlineEditingFirmwareType
indexModel: false
}
}
Row {
spacing: ScreenTools.defaultFontPixelWidth
QGCLabel {
text: qsTr("Vehicle:")
width: _labelWidth
anchors.baseline: offlineVehicleCombo.baseline
}
FactComboBox {
id: offlineVehicleCombo
width: _editFieldWidth
fact: QGroundControl.offlineEditingVehicleType
indexModel: false
}
}
Row {
spacing: ScreenTools.defaultFontPixelWidth
visible: offlineVehicleCombo.currentText != "Multicopter"
QGCLabel {
text: qsTr("Cruise speed:")
width: _labelWidth
anchors.baseline: cruiseSpeedField.baseline
}
FactTextField {
id: cruiseSpeedField
width: _editFieldWidth
fact: QGroundControl.offlineEditingCruiseSpeed
enabled: true
}
}
Row {
spacing: ScreenTools.defaultFontPixelWidth
visible: offlineVehicleCombo.currentText != "Fixedwing"
QGCLabel {
id: hoverSpeedLabel
text: qsTr("Hover speed:")
width: _labelWidth
anchors.baseline: hoverSpeedField.baseline
}
FactTextField {
id: hoverSpeedField
width: _editFieldWidth
fact: QGroundControl.offlineEditingHoverSpeed
enabled: true
}
}
}
}
//-----------------------------------------------------------------
//-- Miscelanous //-- Miscelanous
Item { Item {
width: qgcView.width * 0.8 width: qgcView.width * 0.8
...@@ -274,7 +195,7 @@ QGCView { ...@@ -274,7 +195,7 @@ QGCView {
} }
QGCLabel { QGCLabel {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: qsTr("(Requires Restart)") text: _requiresRestart
} }
} }
//----------------------------------------------------------------- //-----------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment