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
801221a8
Commit
801221a8
authored
Sep 26, 2017
by
Don Gagne
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial Structure Scan support
parent
de55d6e8
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
1041 additions
and
2 deletions
+1041
-2
qgroundcontrol.pro
qgroundcontrol.pro
+2
-0
qgroundcontrol.qrc
qgroundcontrol.qrc
+3
-1
ComplexMissionItem.h
src/MissionManager/ComplexMissionItem.h
+3
-0
MissionController.cc
src/MissionManager/MissionController.cc
+8
-0
MissionController.h
src/MissionManager/MissionController.h
+1
-0
QGCMapPolygon.cc
src/MissionManager/QGCMapPolygon.cc
+10
-0
QGCMapPolygon.h
src/MissionManager/QGCMapPolygon.h
+3
-0
StructureScan.SettingsGroup.json
src/MissionManager/StructureScan.SettingsGroup.json
+35
-0
StructureScanComplexItem.cc
src/MissionManager/StructureScanComplexItem.cc
+519
-0
StructureScanComplexItem.h
src/MissionManager/StructureScanComplexItem.h
+162
-0
SurveyMissionItem.cc
src/MissionManager/SurveyMissionItem.cc
+1
-1
StructureScanEditor.qml
src/PlanView/StructureScanEditor.qml
+143
-0
StructureScanMapVisual.qml
src/PlanView/StructureScanMapVisual.qml
+151
-0
No files found.
qgroundcontrol.pro
View file @
801221a8
...
...
@@ -522,6 +522,7 @@ HEADERS += \
src
/
MissionManager
/
SimpleMissionItem
.
h
\
src
/
MissionManager
/
Section
.
h
\
src
/
MissionManager
/
SpeedSection
.
h
\
src
/
MissionManager
/
StructureScanComplexItem
.
h
\
src
/
MissionManager
/
SurveyMissionItem
.
h
\
src
/
MissionManager
/
VisualMissionItem
.
h
\
src
/
PositionManager
/
PositionManager
.
h
\
...
...
@@ -707,6 +708,7 @@ SOURCES += \
src
/
MissionManager
/
RallyPointManager
.
cc
\
src
/
MissionManager
/
SimpleMissionItem
.
cc
\
src
/
MissionManager
/
SpeedSection
.
cc
\
src
/
MissionManager
/
StructureScanComplexItem
.
cc
\
src
/
MissionManager
/
SurveyMissionItem
.
cc
\
src
/
MissionManager
/
VisualMissionItem
.
cc
\
src
/
PositionManager
/
PositionManager
.
cpp
\
...
...
qgroundcontrol.qrc
View file @
801221a8
...
...
@@ -115,6 +115,7 @@
<file alias="QGroundControl/Controls/SignalStrength.qml">src/ui/toolbar/SignalStrength.qml</file>
<file alias="QGroundControl/Controls/SimpleItemMapVisual.qml">src/PlanView/SimpleItemMapVisual.qml</file>
<file alias="QGroundControl/Controls/SliderSwitch.qml">src/QmlControls/SliderSwitch.qml</file>
<file alias="QGroundControl/Controls/StructureScanMapVisual.qml">src/PlanView/StructureScanMapVisual.qml</file>
<file alias="QGroundControl/Controls/SubMenuButton.qml">src/QmlControls/SubMenuButton.qml</file>
<file alias="QGroundControl/Controls/SurveyMapVisual.qml">src/PlanView/SurveyMapVisual.qml</file>
<file alias="QGroundControl/Controls/VehicleRotationCal.qml">src/QmlControls/VehicleRotationCal.qml</file>
...
...
@@ -179,7 +180,7 @@
<file alias="SetupParameterEditor.qml">src/VehicleSetup/SetupParameterEditor.qml</file>
<file alias="SetupView.qml">src/VehicleSetup/SetupView.qml</file>
<file alias="SimpleItemEditor.qml">src/PlanView/SimpleItemEditor.qml</file>
<file alias="S
urveyItemEditor.qml">src/PlanView/SurveyItem
Editor.qml</file>
<file alias="S
tructureScanEditor.qml">src/PlanView/StructureScan
Editor.qml</file>
<file alias="FWLandingPatternEditor.qml">src/PlanView/FWLandingPatternEditor.qml</file>
<file alias="MissionSettingsEditor.qml">src/PlanView/MissionSettingsEditor.qml</file>
<file alias="TcpSettings.qml">src/ui/preferences/TcpSettings.qml</file>
...
...
@@ -206,6 +207,7 @@
<file alias="QGCMapCircle.Facts.json">src/MissionManager/QGCMapCircle.Facts.json</file>
<file alias="RTK.SettingsGroup.json">src/Settings/RTK.SettingsGroup.json</file>
<file alias="Survey.SettingsGroup.json">src/MissionManager/Survey.SettingsGroup.json</file>
<file alias="StructureScan.SettingsGroup.json">src/MissionManager/StructureScan.SettingsGroup.json</file>
<file alias="Units.SettingsGroup.json">src/Settings/Units.SettingsGroup.json</file>
<file alias="Video.SettingsGroup.json">src/Settings/Video.SettingsGroup.json</file>
<file alias="RallyPoint.FactMetaData.json">src/MissionManager/RallyPoint.FactMetaData.json</file>
...
...
src/MissionManager/ComplexMissionItem.h
View file @
801221a8
...
...
@@ -24,6 +24,7 @@ public:
Q_PROPERTY
(
double
complexDistance
READ
complexDistance
NOTIFY
complexDistanceChanged
)
/// @return The distance covered the complex mission item in meters.
/// Signals complexDistanceChanged
virtual
double
complexDistance
(
void
)
const
=
0
;
/// @return Amount of additional time delay in seconds needed to fly the complex item
...
...
@@ -39,6 +40,7 @@ public:
/// Get the point of complex mission item furthest away from a coordinate
/// @param other QGeoCoordinate to which distance is calculated
/// @return the greatest distance from any point of the complex item to some coordinate
/// Signals greatestDistanceToChanged
virtual
double
greatestDistanceTo
(
const
QGeoCoordinate
&
other
)
const
=
0
;
/// This mission item attribute specifies the type of the complex item.
...
...
@@ -46,6 +48,7 @@ public:
signals:
void
complexDistanceChanged
(
double
complexDistance
);
void
greatestDistanceToChanged
(
void
);
void
additionalTimeDelayChanged
(
double
additionalTimeDelay
);
};
...
...
src/MissionManager/MissionController.cc
View file @
801221a8
...
...
@@ -18,6 +18,7 @@
#include "SimpleMissionItem.h"
#include "SurveyMissionItem.h"
#include "FixedWingLandingComplexItem.h"
#include "StructureScanComplexItem.h"
#include "JsonHelper.h"
#include "ParameterManager.h"
#include "QGroundControlQmlGlobal.h"
...
...
@@ -60,6 +61,7 @@ MissionController::MissionController(PlanMasterController* masterController, QOb
,
_itemsRequested
(
false
)
,
_surveyMissionItemName
(
tr
(
"Survey"
))
,
_fwLandingMissionItemName
(
tr
(
"Fixed Wing Landing"
))
,
_structureScanMissionItemName
(
tr
(
"Structure Scan"
))
,
_appSettings
(
qgcApp
()
->
toolbox
()
->
settingsManager
()
->
appSettings
())
,
_progressPct
(
0
)
{
...
...
@@ -379,6 +381,8 @@ int MissionController::insertComplexMissionItem(QString itemName, QGeoCoordinate
}
}
else
if
(
itemName
==
_fwLandingMissionItemName
)
{
newItem
=
new
FixedWingLandingComplexItem
(
_controllerVehicle
,
_visualItems
);
}
else
if
(
itemName
==
_structureScanMissionItemName
)
{
newItem
=
new
StructureScanComplexItem
(
_controllerVehicle
,
_visualItems
);
}
else
{
qWarning
()
<<
"Internal error: Unknown complex item:"
<<
itemName
;
return
sequenceNumber
;
...
...
@@ -1475,6 +1479,7 @@ void MissionController::_initVisualItem(VisualMissionItem* visualItem)
ComplexMissionItem
*
complexItem
=
qobject_cast
<
ComplexMissionItem
*>
(
visualItem
);
if
(
complexItem
)
{
connect
(
complexItem
,
&
ComplexMissionItem
::
complexDistanceChanged
,
this
,
&
MissionController
::
_recalcMissionFlightStatus
);
connect
(
complexItem
,
&
ComplexMissionItem
::
greatestDistanceToChanged
,
this
,
&
MissionController
::
_recalcMissionFlightStatus
);
connect
(
complexItem
,
&
ComplexMissionItem
::
additionalTimeDelayChanged
,
this
,
&
MissionController
::
_recalcMissionFlightStatus
);
}
else
{
qWarning
()
<<
"ComplexMissionItem not found"
;
...
...
@@ -1769,6 +1774,9 @@ QStringList MissionController::complexMissionItemNames(void) const
if
(
_controllerVehicle
->
fixedWing
())
{
complexItems
.
append
(
_fwLandingMissionItemName
);
}
if
(
_controllerVehicle
->
multiRotor
()
||
_controllerVehicle
->
vtol
())
{
complexItems
.
append
(
_structureScanMissionItemName
);
}
return
complexItems
;
}
...
...
src/MissionManager/MissionController.h
View file @
801221a8
...
...
@@ -231,6 +231,7 @@ private:
MissionFlightStatus_t
_missionFlightStatus
;
QString
_surveyMissionItemName
;
QString
_fwLandingMissionItemName
;
QString
_structureScanMissionItemName
;
AppSettings
*
_appSettings
;
double
_progressPct
;
...
...
src/MissionManager/QGCMapPolygon.cc
View file @
801221a8
...
...
@@ -354,3 +354,13 @@ void QGCMapPolygon::setInteractive(bool interactive)
emit
interactiveChanged
(
interactive
);
}
}
QGeoCoordinate
QGCMapPolygon
::
vertexCoordinate
(
int
vertex
)
const
{
if
(
vertex
>=
0
&&
vertex
<
_polygonPath
.
count
())
{
return
_polygonPath
[
vertex
].
value
<
QGeoCoordinate
>
();
}
else
{
qWarning
()
<<
"QGCMapPolygon::vertexCoordinate bad vertex requested"
;
return
QGeoCoordinate
();
}
}
src/MissionManager/QGCMapPolygon.h
View file @
801221a8
...
...
@@ -55,6 +55,9 @@ public:
/// Returns the path in a list of QGeoCoordinate's format
QList
<
QGeoCoordinate
>
coordinateList
(
void
)
const
;
/// Returns the QGeoCoordinate for the vertex specified
QGeoCoordinate
vertexCoordinate
(
int
vertex
)
const
;
/// Saves the polygon to the json object.
/// @param json Json object to save to
void
saveToJson
(
QJsonObject
&
json
);
...
...
src/MissionManager/StructureScan.SettingsGroup.json
0 → 100644
View file @
801221a8
[
{
"name"
:
"Altitude"
,
"shortDescription"
:
"Altitude for the bottom layer of the structure scan."
,
"type"
:
"double"
,
"units"
:
"m"
,
"decimalPlaces"
:
1
,
"defaultValue"
:
50
},
{
"name"
:
"Layers"
,
"shortDescription"
:
"Number of scan layers."
,
"type"
:
"uint32"
,
"min"
:
1
,
"defaultValue"
:
1
},
{
"name"
:
"Layer distance"
,
"shortDescription"
:
"Distance between each layer."
,
"type"
:
"double"
,
"decimalPlaces"
:
2
,
"min"
:
0
,
"units"
:
"m"
,
"defaultValue"
:
25
},
{
"name"
:
"Trigger distance"
,
"shortDescription"
:
"Distance between each triggering of the camera. 0 specifies not camera trigger."
,
"type"
:
"double"
,
"decimalPlaces"
:
2
,
"min"
:
0
,
"units"
:
"m"
,
"defaultValue"
:
25
}
]
src/MissionManager/StructureScanComplexItem.cc
0 → 100644
View file @
801221a8
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#include "StructureScanComplexItem.h"
#include "JsonHelper.h"
#include "MissionController.h"
#include "QGCGeo.h"
#include "QGroundControlQmlGlobal.h"
#include "QGCQGeoCoordinate.h"
#include "SettingsManager.h"
#include "AppSettings.h"
#include "QGCQGeoCoordinate.h"
#include <QPolygonF>
QGC_LOGGING_CATEGORY
(
StructureScanComplexItemLog
,
"StructureScanComplexItemLog"
)
const
char
*
StructureScanComplexItem
::
jsonComplexItemTypeValue
=
"StructureScan-WIP"
;
const
char
*
StructureScanComplexItem
::
_jsonGridObjectKey
=
"grid"
;
const
char
*
StructureScanComplexItem
::
_jsonGridAltitudeKey
=
"altitude"
;
const
char
*
StructureScanComplexItem
::
_jsonGridAltitudeRelativeKey
=
"relativeAltitude"
;
const
char
*
StructureScanComplexItem
::
_jsonGridAngleKey
=
"angle"
;
const
char
*
StructureScanComplexItem
::
_jsonGridSpacingKey
=
"spacing"
;
const
char
*
StructureScanComplexItem
::
_jsonGridEntryLocationKey
=
"entryLocation"
;
const
char
*
StructureScanComplexItem
::
_jsonTurnaroundDistKey
=
"turnAroundDistance"
;
const
char
*
StructureScanComplexItem
::
_jsonCameraTriggerDistanceKey
=
"cameraTriggerDistance"
;
const
char
*
StructureScanComplexItem
::
_jsonCameraTriggerInTurnaroundKey
=
"cameraTriggerInTurnaround"
;
const
char
*
StructureScanComplexItem
::
_jsonHoverAndCaptureKey
=
"hoverAndCapture"
;
const
char
*
StructureScanComplexItem
::
_jsonGroundResolutionKey
=
"groundResolution"
;
const
char
*
StructureScanComplexItem
::
_jsonFrontalOverlapKey
=
"imageFrontalOverlap"
;
const
char
*
StructureScanComplexItem
::
_jsonSideOverlapKey
=
"imageSideOverlap"
;
const
char
*
StructureScanComplexItem
::
_jsonCameraSensorWidthKey
=
"sensorWidth"
;
const
char
*
StructureScanComplexItem
::
_jsonCameraSensorHeightKey
=
"sensorHeight"
;
const
char
*
StructureScanComplexItem
::
_jsonCameraResolutionWidthKey
=
"resolutionWidth"
;
const
char
*
StructureScanComplexItem
::
_jsonCameraResolutionHeightKey
=
"resolutionHeight"
;
const
char
*
StructureScanComplexItem
::
_jsonCameraFocalLengthKey
=
"focalLength"
;
const
char
*
StructureScanComplexItem
::
_jsonCameraMinTriggerIntervalKey
=
"minTriggerInterval"
;
const
char
*
StructureScanComplexItem
::
_jsonCameraObjectKey
=
"camera"
;
const
char
*
StructureScanComplexItem
::
_jsonCameraNameKey
=
"name"
;
const
char
*
StructureScanComplexItem
::
_jsonManualGridKey
=
"manualGrid"
;
const
char
*
StructureScanComplexItem
::
_jsonCameraOrientationLandscapeKey
=
"orientationLandscape"
;
const
char
*
StructureScanComplexItem
::
_jsonFixedValueIsAltitudeKey
=
"fixedValueIsAltitude"
;
const
char
*
StructureScanComplexItem
::
_jsonRefly90DegreesKey
=
"refly90Degrees"
;
const
char
*
StructureScanComplexItem
::
_altitudeFactName
=
"Altitude"
;
const
char
*
StructureScanComplexItem
::
_layersFactName
=
"Layers"
;
const
char
*
StructureScanComplexItem
::
_layerDistanceFactName
=
"Layer distance"
;
const
char
*
StructureScanComplexItem
::
_cameraTriggerDistanceFactName
=
"Trigger distance"
;
QMap
<
QString
,
FactMetaData
*>
StructureScanComplexItem
::
_metaDataMap
;
StructureScanComplexItem
::
StructureScanComplexItem
(
Vehicle
*
vehicle
,
QObject
*
parent
)
:
ComplexMissionItem
(
vehicle
,
parent
)
,
_sequenceNumber
(
0
)
,
_dirty
(
false
)
,
_altitudeRelative
(
true
)
,
_entryVertex
(
0
)
,
_ignoreRecalc
(
false
)
,
_scanDistance
(
0.0
)
,
_cameraShots
(
0
)
,
_cameraMinTriggerInterval
(
0
)
,
_altitudeFact
(
0
,
_altitudeFactName
,
FactMetaData
::
valueTypeDouble
)
,
_layersFact
(
0
,
_layersFactName
,
FactMetaData
::
valueTypeUint32
)
,
_layerDistanceFact
(
0
,
_layerDistanceFactName
,
FactMetaData
::
valueTypeDouble
)
,
_cameraTriggerDistanceFact
(
0
,
_cameraTriggerDistanceFactName
,
FactMetaData
::
valueTypeDouble
)
{
_editorQml
=
"qrc:/qml/StructureScanEditor.qml"
;
if
(
_metaDataMap
.
isEmpty
())
{
_metaDataMap
=
FactMetaData
::
createMapFromJsonFile
(
QStringLiteral
(
":/json/StructureScan.SettingsGroup.json"
),
this
);
}
_altitudeFact
.
setMetaData
(
_metaDataMap
[
_altitudeFactName
]);
_layersFact
.
setMetaData
(
_metaDataMap
[
_layersFactName
]);
_layerDistanceFact
.
setMetaData
(
_metaDataMap
[
_layerDistanceFactName
]);
_cameraTriggerDistanceFact
.
setMetaData
(
_metaDataMap
[
_cameraTriggerDistanceFactName
]);
_altitudeFact
.
setRawValue
(
_altitudeFact
.
rawDefaultValue
());
_layersFact
.
setRawValue
(
_layersFact
.
rawDefaultValue
());
_layerDistanceFact
.
setRawValue
(
_layerDistanceFact
.
rawDefaultValue
());
_cameraTriggerDistanceFact
.
setRawValue
(
_cameraTriggerDistanceFact
.
rawDefaultValue
());
_altitudeFact
.
setRawValue
(
qgcApp
()
->
toolbox
()
->
settingsManager
()
->
appSettings
()
->
defaultMissionItemAltitude
()
->
rawValue
());
connect
(
&
_altitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
StructureScanComplexItem
::
_setDirty
);
connect
(
&
_layersFact
,
&
Fact
::
valueChanged
,
this
,
&
StructureScanComplexItem
::
_setDirty
);
connect
(
&
_layerDistanceFact
,
&
Fact
::
valueChanged
,
this
,
&
StructureScanComplexItem
::
_setDirty
);
connect
(
&
_cameraTriggerDistanceFact
,
&
Fact
::
valueChanged
,
this
,
&
StructureScanComplexItem
::
_setDirty
);
connect
(
this
,
&
StructureScanComplexItem
::
altitudeRelativeChanged
,
this
,
&
StructureScanComplexItem
::
_setDirty
);
connect
(
this
,
&
StructureScanComplexItem
::
altitudeRelativeChanged
,
this
,
&
StructureScanComplexItem
::
coordinateHasRelativeAltitudeChanged
);
connect
(
this
,
&
StructureScanComplexItem
::
altitudeRelativeChanged
,
this
,
&
StructureScanComplexItem
::
exitCoordinateHasRelativeAltitudeChanged
);
connect
(
&
_altitudeFact
,
&
Fact
::
valueChanged
,
this
,
&
StructureScanComplexItem
::
_updateCoordinateAltitudes
);
connect
(
&
_mapPolygon
,
&
QGCMapPolygon
::
dirtyChanged
,
this
,
&
StructureScanComplexItem
::
_polygonDirtyChanged
);
connect
(
&
_mapPolygon
,
&
QGCMapPolygon
::
countChanged
,
this
,
&
StructureScanComplexItem
::
_polygonCountChanged
);
connect
(
&
_mapPolygon
,
&
QGCMapPolygon
::
pathChanged
,
this
,
&
StructureScanComplexItem
::
_polygonPathChanged
);
}
void
StructureScanComplexItem
::
_setScanDistance
(
double
scanDistance
)
{
if
(
!
qFuzzyCompare
(
_scanDistance
,
scanDistance
))
{
_scanDistance
=
scanDistance
;
emit
complexDistanceChanged
(
_scanDistance
);
}
}
void
StructureScanComplexItem
::
_setCameraShots
(
int
cameraShots
)
{
if
(
_cameraShots
!=
cameraShots
)
{
_cameraShots
=
cameraShots
;
emit
cameraShotsChanged
(
this
->
cameraShots
());
}
}
void
StructureScanComplexItem
::
_clearInternal
(
void
)
{
setDirty
(
true
);
emit
specifiesCoordinateChanged
();
emit
lastSequenceNumberChanged
(
lastSequenceNumber
());
}
void
StructureScanComplexItem
::
_polygonCountChanged
(
int
count
)
{
Q_UNUSED
(
count
);
emit
lastSequenceNumberChanged
(
lastSequenceNumber
());
}
int
StructureScanComplexItem
::
lastSequenceNumber
(
void
)
const
{
return
_sequenceNumber
+
((
_mapPolygon
.
count
()
+
1
)
*
_layersFact
.
rawValue
().
toInt
())
+
// 1 waypoint for each polygon vertex + 1 to go back to first polygon vertex
1
;
// Gimbal yaw command
}
void
StructureScanComplexItem
::
setDirty
(
bool
dirty
)
{
if
(
_dirty
!=
dirty
)
{
_dirty
=
dirty
;
emit
dirtyChanged
(
_dirty
);
}
}
void
StructureScanComplexItem
::
save
(
QJsonArray
&
missionItems
)
{
Q_UNUSED
(
missionItems
);
#if 0
QJsonObject saveObject;
saveObject[JsonHelper::jsonVersionKey] = 3;
saveObject[VisualMissionItem::jsonTypeKey] = VisualMissionItem::jsonTypeComplexItemValue;
saveObject[ComplexMissionItem::jsonComplexItemTypeKey] = jsonComplexItemTypeValue;
saveObject[_jsonManualGridKey] = _manualGridFact.rawValue().toBool();
saveObject[_jsonFixedValueIsAltitudeKey] = _fixedValueIsAltitudeFact.rawValue().toBool();
saveObject[_jsonHoverAndCaptureKey] = _hoverAndCaptureFact.rawValue().toBool();
saveObject[_jsonRefly90DegreesKey] = _refly90Degrees;
saveObject[_jsonCameraTriggerDistanceKey] = _cameraTriggerDistanceFact.rawValue().toDouble();
QJsonObject gridObject;
gridObject[_jsonGridAltitudeKey] = _gridAltitudeFact.rawValue().toDouble();
gridObject[_jsonGridAltitudeRelativeKey] = _gridAltitudeRelativeFact.rawValue().toBool();
gridObject[_jsonGridAngleKey] = _gridAngleFact.rawValue().toDouble();
gridObject[_jsonGridSpacingKey] = _gridSpacingFact.rawValue().toDouble();
gridObject[_jsonGridEntryLocationKey] = _gridEntryLocationFact.rawValue().toDouble();
gridObject[_jsonTurnaroundDistKey] = _turnaroundDistFact.rawValue().toDouble();
saveObject[_jsonGridObjectKey] = gridObject;
if (!_manualGridFact.rawValue().toBool()) {
QJsonObject cameraObject;
cameraObject[_jsonCameraNameKey] = _cameraFact.rawValue().toString();
cameraObject[_jsonCameraOrientationLandscapeKey] = _cameraOrientationLandscapeFact.rawValue().toBool();
cameraObject[_jsonCameraSensorWidthKey] = _cameraSensorWidthFact.rawValue().toDouble();
cameraObject[_jsonCameraSensorHeightKey] = _cameraSensorHeightFact.rawValue().toDouble();
cameraObject[_jsonCameraResolutionWidthKey] = _cameraResolutionWidthFact.rawValue().toDouble();
cameraObject[_jsonCameraResolutionHeightKey] = _cameraResolutionHeightFact.rawValue().toDouble();
cameraObject[_jsonCameraFocalLengthKey] = _cameraFocalLengthFact.rawValue().toDouble();
cameraObject[_jsonCameraMinTriggerIntervalKey] = _cameraMinTriggerInterval;
cameraObject[_jsonGroundResolutionKey] = _groundResolutionFact.rawValue().toDouble();
cameraObject[_jsonFrontalOverlapKey] = _frontalOverlapFact.rawValue().toInt();
cameraObject[_jsonSideOverlapKey] = _sideOverlapFact.rawValue().toInt();
saveObject[_jsonCameraObjectKey] = cameraObject;
}
// Polygon shape
_mapPolygon.saveToJson(saveObject);
missionItems.append(saveObject);
#endif
}
void
StructureScanComplexItem
::
setSequenceNumber
(
int
sequenceNumber
)
{
if
(
_sequenceNumber
!=
sequenceNumber
)
{
_sequenceNumber
=
sequenceNumber
;
emit
sequenceNumberChanged
(
sequenceNumber
);
emit
lastSequenceNumberChanged
(
lastSequenceNumber
());
}
}
bool
StructureScanComplexItem
::
load
(
const
QJsonObject
&
complexObject
,
int
sequenceNumber
,
QString
&
errorString
)
{
#if 0
QJsonObject v2Object = complexObject;
// We need to pull version first to determine what validation/conversion needs to be performed.
QList<JsonHelper::KeyValidateInfo> versionKeyInfoList = {
{ JsonHelper::jsonVersionKey, QJsonValue::Double, true },
};
if (!JsonHelper::validateKeys(v2Object, versionKeyInfoList, errorString)) {
return false;
}
int version = v2Object[JsonHelper::jsonVersionKey].toInt();
if (version != 2 && version != 3) {
errorString = tr("%1 does not support this version of survey items").arg(qgcApp()->applicationName());
return false;
}
if (version == 2) {
// Convert to v3
if (v2Object.contains(VisualMissionItem::jsonTypeKey) && v2Object[VisualMissionItem::jsonTypeKey].toString() == QStringLiteral("survey")) {
v2Object[VisualMissionItem::jsonTypeKey] = VisualMissionItem::jsonTypeComplexItemValue;
v2Object[ComplexMissionItem::jsonComplexItemTypeKey] = jsonComplexItemTypeValue;
}
}
QList<JsonHelper::KeyValidateInfo> mainKeyInfoList = {
{ JsonHelper::jsonVersionKey, QJsonValue::Double, true },
{ VisualMissionItem::jsonTypeKey, QJsonValue::String, true },
{ ComplexMissionItem::jsonComplexItemTypeKey, QJsonValue::String, true },
{ QGCMapPolygon::jsonPolygonKey, QJsonValue::Array, true },
{ _jsonGridObjectKey, QJsonValue::Object, true },
{ _jsonCameraObjectKey, QJsonValue::Object, false },
{ _jsonCameraTriggerDistanceKey, QJsonValue::Double, true },
{ _jsonManualGridKey, QJsonValue::Bool, true },
{ _jsonFixedValueIsAltitudeKey, QJsonValue::Bool, true },
{ _jsonHoverAndCaptureKey, QJsonValue::Bool, false },
{ _jsonRefly90DegreesKey, QJsonValue::Bool, false },
};
if (!JsonHelper::validateKeys(v2Object, mainKeyInfoList, errorString)) {
return false;
}
QString itemType = v2Object[VisualMissionItem::jsonTypeKey].toString();
QString complexType = v2Object[ComplexMissionItem::jsonComplexItemTypeKey].toString();
if (itemType != VisualMissionItem::jsonTypeComplexItemValue || complexType != jsonComplexItemTypeValue) {
errorString = tr("%1 does not support loading this complex mission item type: %2:%3").arg(qgcApp()->applicationName()).arg(itemType).arg(complexType);
return false;
}
_ignoreRecalc = true;
_mapPolygon.clear();
setSequenceNumber(sequenceNumber);
_manualGridFact.setRawValue (v2Object[_jsonManualGridKey].toBool(true));
_fixedValueIsAltitudeFact.setRawValue (v2Object[_jsonFixedValueIsAltitudeKey].toBool(true));
_gridAltitudeRelativeFact.setRawValue (v2Object[_jsonGridAltitudeRelativeKey].toBool(true));
_hoverAndCaptureFact.setRawValue (v2Object[_jsonHoverAndCaptureKey].toBool(false));
_refly90Degrees = v2Object[_jsonRefly90DegreesKey].toBool(false);
QList<JsonHelper::KeyValidateInfo> gridKeyInfoList = {
{ _jsonGridAltitudeKey, QJsonValue::Double, true },
{ _jsonGridAltitudeRelativeKey, QJsonValue::Bool, true },
{ _jsonGridAngleKey, QJsonValue::Double, true },
{ _jsonGridSpacingKey, QJsonValue::Double, true },
{ _jsonGridEntryLocationKey, QJsonValue::Double, false },
{ _jsonTurnaroundDistKey, QJsonValue::Double, true },
};
QJsonObject gridObject = v2Object[_jsonGridObjectKey].toObject();
if (!JsonHelper::validateKeys(gridObject, gridKeyInfoList, errorString)) {
return false;
}
_gridAltitudeFact.setRawValue (gridObject[_jsonGridAltitudeKey].toDouble());
_gridAngleFact.setRawValue (gridObject[_jsonGridAngleKey].toDouble());
_gridSpacingFact.setRawValue (gridObject[_jsonGridSpacingKey].toDouble());
_turnaroundDistFact.setRawValue (gridObject[_jsonTurnaroundDistKey].toDouble());
_cameraTriggerDistanceFact.setRawValue (v2Object[_jsonCameraTriggerDistanceKey].toDouble());
if (gridObject.contains(_jsonGridEntryLocationKey)) {
_gridEntryLocationFact.setRawValue(gridObject[_jsonGridEntryLocationKey].toDouble());
} else {
_gridEntryLocationFact.setRawValue(_gridEntryLocationFact.rawDefaultValue());
}
if (!_manualGridFact.rawValue().toBool()) {
if (!v2Object.contains(_jsonCameraObjectKey)) {
errorString = tr("%1 but %2 object is missing").arg("manualGrid = false").arg("camera");
return false;
}
QJsonObject cameraObject = v2Object[_jsonCameraObjectKey].toObject();
// Older code had typo on "imageSideOverlap" incorrectly being "imageSizeOverlap"
QString incorrectImageSideOverlap = "imageSizeOverlap";
if (cameraObject.contains(incorrectImageSideOverlap)) {
cameraObject[_jsonSideOverlapKey] = cameraObject[incorrectImageSideOverlap];
cameraObject.remove(incorrectImageSideOverlap);
}
QList<JsonHelper::KeyValidateInfo> cameraKeyInfoList = {
{ _jsonGroundResolutionKey, QJsonValue::Double, true },
{ _jsonFrontalOverlapKey, QJsonValue::Double, true },
{ _jsonSideOverlapKey, QJsonValue::Double, true },
{ _jsonCameraSensorWidthKey, QJsonValue::Double, true },
{ _jsonCameraSensorHeightKey, QJsonValue::Double, true },
{ _jsonCameraResolutionWidthKey, QJsonValue::Double, true },
{ _jsonCameraResolutionHeightKey, QJsonValue::Double, true },
{ _jsonCameraFocalLengthKey, QJsonValue::Double, true },
{ _jsonCameraNameKey, QJsonValue::String, true },
{ _jsonCameraOrientationLandscapeKey, QJsonValue::Bool, true },
{ _jsonCameraMinTriggerIntervalKey, QJsonValue::Double, false },
};
if (!JsonHelper::validateKeys(cameraObject, cameraKeyInfoList, errorString)) {
return false;
}
_cameraFact.setRawValue(cameraObject[_jsonCameraNameKey].toString());
_cameraOrientationLandscapeFact.setRawValue(cameraObject[_jsonCameraOrientationLandscapeKey].toBool(true));
_groundResolutionFact.setRawValue (cameraObject[_jsonGroundResolutionKey].toDouble());
_frontalOverlapFact.setRawValue (cameraObject[_jsonFrontalOverlapKey].toInt());
_sideOverlapFact.setRawValue (cameraObject[_jsonSideOverlapKey].toInt());
_cameraSensorWidthFact.setRawValue (cameraObject[_jsonCameraSensorWidthKey].toDouble());
_cameraSensorHeightFact.setRawValue (cameraObject[_jsonCameraSensorHeightKey].toDouble());
_cameraResolutionWidthFact.setRawValue (cameraObject[_jsonCameraResolutionWidthKey].toDouble());
_cameraResolutionHeightFact.setRawValue (cameraObject[_jsonCameraResolutionHeightKey].toDouble());
_cameraFocalLengthFact.setRawValue (cameraObject[_jsonCameraFocalLengthKey].toDouble());
_cameraMinTriggerInterval = cameraObject[_jsonCameraMinTriggerIntervalKey].toDouble(0);
}
// Polygon shape
/// Load a polygon from json
/// @param json Json object to load from
/// @param required true: no polygon in object will generate error
/// @param errorString Error string if return is false
/// @return true: success, false: failure (errorString set)
if (!_mapPolygon.loadFromJson(v2Object, true /* required */, errorString)) {
_mapPolygon.clear();
return false;
}
_ignoreRecalc = false;
_generateGrid();
return true;
#else
Q_UNUSED
(
complexObject
);
Q_UNUSED
(
sequenceNumber
);
Q_UNUSED
(
errorString
);
return
false
;
#endif
}
void
StructureScanComplexItem
::
_polygonPathChanged
(
void
)
{
emit
coordinateChanged
(
coordinate
());
emit
exitCoordinateChanged
(
exitCoordinate
());
emit
greatestDistanceToChanged
();
}
double
StructureScanComplexItem
::
greatestDistanceTo
(
const
QGeoCoordinate
&
other
)
const
{
double
greatestDistance
=
0.0
;
QList
<
QGeoCoordinate
>
vertices
=
_mapPolygon
.
coordinateList
();
for
(
int
i
=
0
;
i
<
vertices
.
count
();
i
++
)
{
QGeoCoordinate
vertex
=
vertices
[
i
];
double
distance
=
vertex
.
distanceTo
(
other
);
if
(
distance
>
greatestDistance
)
{
greatestDistance
=
distance
;
}
}
return
greatestDistance
;
}
bool
StructureScanComplexItem
::
specifiesCoordinate
(
void
)
const
{
return
_mapPolygon
.
count
()
>
2
;
}
void
StructureScanComplexItem
::
appendMissionItems
(
QList
<
MissionItem
*>&
items
,
QObject
*
missionItemParent
)
{
int
seqNum
=
_sequenceNumber
;
double
baseAltitude
=
_altitudeFact
.
rawValue
().
toDouble
();
MissionItem
*
item
=
new
MissionItem
(
seqNum
++
,
MAV_CMD_DO_MOUNT_CONTROL
,
MAV_FRAME_MISSION
,
0
,
// Gimbal pitch
0
,
// Gimbal roll
90
,
// Gimbal yaw
0
,
0
,
0
,
// param 4-6 not used
MAV_MOUNT_MODE_MAVLINK_TARGETING
,
true
,
// autoContinue
false
,
// isCurrentItem
missionItemParent
);
items
.
append
(
item
);
for
(
int
layer
=
0
;
layer
<
_layersFact
.
rawValue
().
toInt
();
layer
++
)
{
double
layerAltitude
=
baseAltitude
+
(
layer
*
_layerDistanceFact
.
rawValue
().
toDouble
());
for
(
int
i
=
0
;
i
<
_mapPolygon
.
count
();
i
++
)
{
QGeoCoordinate
vertexCoord
=
_mapPolygon
.
pathModel
().
value
<
QGCQGeoCoordinate
*>
(
i
)
->
coordinate
();
MissionItem
*
item
=
new
MissionItem
(
seqNum
++
,
MAV_CMD_NAV_WAYPOINT
,
_altitudeRelative
?
MAV_FRAME_GLOBAL_RELATIVE_ALT
:
MAV_FRAME_GLOBAL
,
0
,
// No hold time
0.0
,
// No acceptance radius specified
0.0
,
// Pass through waypoint
90
,
//std::numeric_limits<double>::quiet_NaN(), // Yaw unchanged
vertexCoord
.
latitude
(),
vertexCoord
.
longitude
(),
layerAltitude
,
true
,
// autoContinue
false
,
// isCurrentItem
missionItemParent
);
items
.
append
(
item
);
}
QGeoCoordinate
vertexCoord
=
_mapPolygon
.
pathModel
().
value
<
QGCQGeoCoordinate
*>
(
0
)
->
coordinate
();
MissionItem
*
item
=
new
MissionItem
(
seqNum
++
,
MAV_CMD_NAV_WAYPOINT
,
_altitudeRelative
?
MAV_FRAME_GLOBAL_RELATIVE_ALT
:
MAV_FRAME_GLOBAL
,
0
,
// No hold time
0.0
,
// No acceptance radius specified
0.0
,
// Pass through waypoint
std
::
numeric_limits
<
double
>::
quiet_NaN
(),
// Yaw unchanged
vertexCoord
.
latitude
(),
vertexCoord
.
longitude
(),
layerAltitude
,
true
,
// autoContinue
false
,
// isCurrentItem
missionItemParent
);
items
.
append
(
item
);
}
}
int
StructureScanComplexItem
::
cameraShots
(
void
)
const
{
return
true
/*_triggerCamera()*/
?
_cameraShots
:
0
;
}
void
StructureScanComplexItem
::
setMissionFlightStatus
(
MissionController
::
MissionFlightStatus_t
&
missionFlightStatus
)
{
ComplexMissionItem
::
setMissionFlightStatus
(
missionFlightStatus
);
if
(
!
qFuzzyCompare
(
_cruiseSpeed
,
missionFlightStatus
.
vehicleSpeed
))
{
_cruiseSpeed
=
missionFlightStatus
.
vehicleSpeed
;
emit
timeBetweenShotsChanged
();
}
}
void
StructureScanComplexItem
::
_setDirty
(
void
)
{
setDirty
(
true
);
}
void
StructureScanComplexItem
::
applyNewAltitude
(
double
newAltitude
)
{
_altitudeFact
.
setRawValue
(
newAltitude
);
}
void
StructureScanComplexItem
::
_polygonDirtyChanged
(
bool
dirty
)
{
if
(
dirty
)
{
setDirty
(
true
);
}
}
double
StructureScanComplexItem
::
timeBetweenShots
(
void
)
const
{
return
_cruiseSpeed
==
0
?
0
:
_cameraTriggerDistanceFact
.
rawValue
().
toDouble
()
/
_cruiseSpeed
;
}
QGeoCoordinate
StructureScanComplexItem
::
coordinate
(
void
)
const
{
if
(
_mapPolygon
.
count
()
>
0
)
{
int
entryVertex
=
qMax
(
qMin
(
_entryVertex
,
_mapPolygon
.
count
()
-
1
),
0
);
return
_mapPolygon
.
vertexCoordinate
(
entryVertex
);
}
else
{
return
QGeoCoordinate
();
}
}
QGeoCoordinate
StructureScanComplexItem
::
exitCoordinate
(
void
)
const
{
return
coordinate
();
}
void
StructureScanComplexItem
::
_updateCoordinateAltitudes
(
void
)
{
emit
coordinateChanged
(
coordinate
());
emit
exitCoordinateChanged
(
exitCoordinate
());
}
void
StructureScanComplexItem
::
rotateEntryPoint
(
void
)
{
_entryVertex
++
;
if
(
_entryVertex
>=
_mapPolygon
.
count
())
{
_entryVertex
=
0
;
}
emit
coordinateChanged
(
coordinate
());
emit
exitCoordinateChanged
(
exitCoordinate
());
}
src/MissionManager/StructureScanComplexItem.h
0 → 100644
View file @
801221a8
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#ifndef StructureScanComplexItem_H
#define StructureScanComplexItem_H
#include "ComplexMissionItem.h"
#include "MissionItem.h"
#include "SettingsFact.h"
#include "QGCLoggingCategory.h"
#include "QGCMapPolygon.h"
Q_DECLARE_LOGGING_CATEGORY
(
StructureScanComplexItemLog
)
class
StructureScanComplexItem
:
public
ComplexMissionItem
{
Q_OBJECT
public:
StructureScanComplexItem
(
Vehicle
*
vehicle
,
QObject
*
parent
=
NULL
);
Q_PROPERTY
(
Fact
*
altitude
READ
altitude
CONSTANT
)
Q_PROPERTY
(
Fact
*
layers
READ
layers
CONSTANT
)
Q_PROPERTY
(
Fact
*
layerDistance
READ
layerDistance
CONSTANT
)
Q_PROPERTY
(
Fact
*
cameraTriggerDistance
READ
cameraTriggerDistance
CONSTANT
)
Q_PROPERTY
(
bool
altitudeRelative
MEMBER
_altitudeRelative
NOTIFY
altitudeRelativeChanged
)
Q_PROPERTY
(
int
cameraShots
READ
cameraShots
NOTIFY
cameraShotsChanged
)
Q_PROPERTY
(
double
timeBetweenShots
READ
timeBetweenShots
NOTIFY
timeBetweenShotsChanged
)
Q_PROPERTY
(
double
cameraMinTriggerInterval
MEMBER
_cameraMinTriggerInterval
NOTIFY
cameraMinTriggerIntervalChanged
)
Q_PROPERTY
(
QGCMapPolygon
*
mapPolygon
READ
mapPolygon
CONSTANT
)
Fact
*
altitude
(
void
)
{
return
&
_altitudeFact
;
}
Fact
*
layers
(
void
)
{
return
&
_layersFact
;
}
Fact
*
layerDistance
(
void
)
{
return
&
_layerDistanceFact
;
}
Fact
*
cameraTriggerDistance
(
void
)
{
return
&
_cameraTriggerDistanceFact
;
}
int
cameraShots
(
void
)
const
;
double
timeBetweenShots
(
void
)
const
;
QGCMapPolygon
*
mapPolygon
(
void
)
{
return
&
_mapPolygon
;
}
Q_INVOKABLE
void
rotateEntryPoint
(
void
);
// Overrides from ComplexMissionItem
double
complexDistance
(
void
)
const
final
{
return
_scanDistance
;
}
int
lastSequenceNumber
(
void
)
const
final
;
bool
load
(
const
QJsonObject
&
complexObject
,
int
sequenceNumber
,
QString
&
errorString
)
final
;
double
greatestDistanceTo
(
const
QGeoCoordinate
&
other
)
const
final
;
QString
mapVisualQML
(
void
)
const
final
{
return
QStringLiteral
(
"StructureScanMapVisual.qml"
);
}
// Overrides from VisualMissionItem
bool
dirty
(
void
)
const
final
{
return
_dirty
;
}
bool
isSimpleItem
(
void
)
const
final
{
return
false
;
}
bool
isStandaloneCoordinate
(
void
)
const
final
{
return
false
;
}
bool
specifiesCoordinate
(
void
)
const
final
;
bool
specifiesAltitudeOnly
(
void
)
const
final
{
return
false
;
}
QString
commandDescription
(
void
)
const
final
{
return
tr
(
"Structure Scan"
);
}
QString
commandName
(
void
)
const
final
{
return
tr
(
"Structure Scan"
);
}
QString
abbreviation
(
void
)
const
final
{
return
"S"
;
}
QGeoCoordinate
coordinate
(
void
)
const
final
;
QGeoCoordinate
exitCoordinate
(
void
)
const
final
;
int
sequenceNumber
(
void
)
const
final
{
return
_sequenceNumber
;
}
double
specifiedFlightSpeed
(
void
)
final
{
return
std
::
numeric_limits
<
double
>::
quiet_NaN
();
}
double
specifiedGimbalYaw
(
void
)
final
{
return
std
::
numeric_limits
<
double
>::
quiet_NaN
();
}
void
appendMissionItems
(
QList
<
MissionItem
*>&
items
,
QObject
*
missionItemParent
)
final
;
void
setMissionFlightStatus
(
MissionController
::
MissionFlightStatus_t
&
missionFlightStatus
)
final
;
void
applyNewAltitude
(
double
newAltitude
)
final
;
bool
coordinateHasRelativeAltitude
(
void
)
const
final
{
return
_altitudeRelative
;
}
bool
exitCoordinateHasRelativeAltitude
(
void
)
const
final
{
return
_altitudeRelative
;
}
bool
exitCoordinateSameAsEntry
(
void
)
const
final
{
return
true
;
}
void
setDirty
(
bool
dirty
)
final
;
void
setCoordinate
(
const
QGeoCoordinate
&
coordinate
)
final
{
Q_UNUSED
(
coordinate
);
}
void
setSequenceNumber
(
int
sequenceNumber
)
final
;
void
save
(
QJsonArray
&
missionItems
)
final
;
static
const
char
*
jsonComplexItemTypeValue
;
signals:
void
cameraShotsChanged
(
int
cameraShots
);
void
timeBetweenShotsChanged
(
void
);
void
cameraMinTriggerIntervalChanged
(
double
cameraMinTriggerInterval
);
void
altitudeRelativeChanged
(
bool
altitudeRelative
);
private
slots
:
void
_setDirty
(
void
);
void
_polygonDirtyChanged
(
bool
dirty
);
void
_polygonCountChanged
(
int
count
);
void
_polygonPathChanged
(
void
);
void
_clearInternal
(
void
);
void
_updateCoordinateAltitudes
(
void
);
private:
void
_setExitCoordinate
(
const
QGeoCoordinate
&
coordinate
);
void
_setScanDistance
(
double
scanDistance
);
void
_setCameraShots
(
int
cameraShots
);
double
_triggerDistance
(
void
)
const
;
int
_sequenceNumber
;
bool
_dirty
;
QGCMapPolygon
_mapPolygon
;
bool
_altitudeRelative
;
int
_entryVertex
;
// Polygon vertext which is used as the mission entry point
bool
_ignoreRecalc
;
double
_scanDistance
;
int
_cameraShots
;
double
_timeBetweenShots
;
double
_cameraMinTriggerInterval
;
double
_cruiseSpeed
;
static
QMap
<
QString
,
FactMetaData
*>
_metaDataMap
;
Fact
_altitudeFact
;
Fact
_layersFact
;
Fact
_layerDistanceFact
;
Fact
_cameraTriggerDistanceFact
;
static
const
char
*
_altitudeFactName
;
static
const
char
*
_layersFactName
;
static
const
char
*
_layerDistanceFactName
;
static
const
char
*
_cameraTriggerDistanceFactName
;
static
const
char
*
_jsonGridObjectKey
;
static
const
char
*
_jsonGridAltitudeKey
;
static
const
char
*
_jsonGridAltitudeRelativeKey
;
static
const
char
*
_jsonGridAngleKey
;
static
const
char
*
_jsonGridSpacingKey
;
static
const
char
*
_jsonGridEntryLocationKey
;
static
const
char
*
_jsonTurnaroundDistKey
;
static
const
char
*
_jsonCameraTriggerDistanceKey
;
static
const
char
*
_jsonCameraTriggerInTurnaroundKey
;
static
const
char
*
_jsonHoverAndCaptureKey
;
static
const
char
*
_jsonGroundResolutionKey
;
static
const
char
*
_jsonFrontalOverlapKey
;
static
const
char
*
_jsonSideOverlapKey
;
static
const
char
*
_jsonCameraSensorWidthKey
;
static
const
char
*
_jsonCameraSensorHeightKey
;
static
const
char
*
_jsonCameraResolutionWidthKey
;
static
const
char
*
_jsonCameraResolutionHeightKey
;
static
const
char
*
_jsonCameraFocalLengthKey
;
static
const
char
*
_jsonCameraMinTriggerIntervalKey
;
static
const
char
*
_jsonManualGridKey
;
static
const
char
*
_jsonCameraObjectKey
;
static
const
char
*
_jsonCameraNameKey
;
static
const
char
*
_jsonCameraOrientationLandscapeKey
;
static
const
char
*
_jsonFixedValueIsAltitudeKey
;
static
const
char
*
_jsonRefly90DegreesKey
;
static
const
int
_hoverAndCaptureDelaySeconds
=
1
;
};
#endif
src/MissionManager/SurveyMissionItem.cc
View file @
801221a8
...
...
@@ -1322,7 +1322,7 @@ double SurveyMissionItem::timeBetweenShots(void) const
return
_cruiseSpeed
==
0
?
0
:
_triggerDistance
()
/
_cruiseSpeed
;
}
void
SurveyMissionItem
::
setMissionFlightStatus
(
MissionController
::
MissionFlightStatus_t
&
missionFlightStatus
)
void
SurveyMissionItem
::
setMissionFlightStatus
(
MissionController
::
MissionFlightStatus_t
&
missionFlightStatus
)
{
ComplexMissionItem
::
setMissionFlightStatus
(
missionFlightStatus
);
if
(
!
qFuzzyCompare
(
_cruiseSpeed
,
missionFlightStatus
.
vehicleSpeed
))
{
...
...
src/PlanView/StructureScanEditor.qml
0 → 100644
View file @
801221a8
import
QtQuick
2.3
import
QtQuick
.
Controls
1.2
import
QtQuick
.
Controls
.
Styles
1.4
import
QtQuick
.
Dialogs
1.2
import
QtQuick
.
Extras
1.4
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
import
QGroundControl
.
FlightMap
1.0
// Editor for Survery mission items
Rectangle
{
id
:
_root
height
:
visible
?
(
editorColumn
.
height
+
(
_margin
*
2
))
:
0
width
:
availableWidth
color
:
qgcPal
.
windowShadeDark
radius
:
_radius
// The following properties must be available up the hierarchy chain
//property real availableWidth ///< Width for control
//property var missionItem ///< Mission Item for editor
property
real
_margin
:
ScreenTools
.
defaultFontPixelWidth
/
2
property
real
_fieldWidth
:
ScreenTools
.
defaultFontPixelWidth
*
10.5
property
var
_vehicle
:
QGroundControl
.
multiVehicleManager
.
activeVehicle
?
QGroundControl
.
multiVehicleManager
.
activeVehicle
:
QGroundControl
.
multiVehicleManager
.
offlineEditingVehicle
function
polygonCaptureStarted
()
{
missionItem
.
clearPolygon
()
}
function
polygonCaptureFinished
(
coordinates
)
{
for
(
var
i
=
0
;
i
<
coordinates
.
length
;
i
++
)
{
missionItem
.
addPolygonCoordinate
(
coordinates
[
i
])
}
}
function
polygonAdjustVertex
(
vertexIndex
,
vertexCoordinate
)
{
missionItem
.
adjustPolygonCoordinate
(
vertexIndex
,
vertexCoordinate
)
}
function
polygonAdjustStarted
()
{
}
function
polygonAdjustFinished
()
{
}
QGCPalette
{
id
:
qgcPal
;
colorGroupEnabled
:
true
}
Column
{
id
:
editorColumn
anchors.margins
:
_margin
anchors.top
:
parent
.
top
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
spacing
:
_margin
QGCLabel
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
text
:
qsTr
(
"
WARNING: WORK IN PROGRESS. USE AT YOUR OWN RISK.
"
)
wrapMode
:
Text
.
WordWrap
color
:
qgcPal
.
warningText
}
QGCLabel
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
text
:
qsTr
(
"
WARNING: Photo interval is below minimum interval (%1 secs) supported by camera.
"
).
arg
(
missionItem
.
cameraMinTriggerInterval
.
toFixed
(
1
))
wrapMode
:
Text
.
WordWrap
color
:
qgcPal
.
warningText
visible
:
missionItem
.
cameraShots
>
0
&&
missionItem
.
cameraMinTriggerInterval
!==
0
&&
missionItem
.
cameraMinTriggerInterval
>
missionItem
.
timeBetweenShots
}
GridLayout
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
columnSpacing
:
_margin
rowSpacing
:
_margin
columns
:
2
QGCLabel
{
text
:
qsTr
(
"
Altitude
"
)
}
FactTextField
{
fact
:
missionItem
.
altitude
Layout.fillWidth
:
true
}
QGCLabel
{
text
:
qsTr
(
"
Layers
"
)
}
FactTextField
{
fact
:
missionItem
.
layers
Layout.fillWidth
:
true
}
QGCLabel
{
text
:
qsTr
(
"
Layer distance
"
)
}
FactTextField
{
fact
:
missionItem
.
layerDistance
Layout.fillWidth
:
true
}
QGCLabel
{
text
:
qsTr
(
"
Trigger Distance
"
)
}
FactTextField
{
fact
:
missionItem
.
cameraTriggerDistance
Layout.fillWidth
:
true
}
QGCCheckBox
{
text
:
qsTr
(
"
Relative altitude
"
)
checked
:
missionItem
.
altitudeRelative
Layout.columnSpan
:
2
onClicked
:
missionItem
.
altitudeRelative
=
checked
}
}
QGCLabel
{
text
:
qsTr
(
"
Point camera to structure using:
"
)
}
QGCRadioButton
{
text
:
qsTr
(
"
Vehicle yaw
"
);
enabled
:
false
}
QGCRadioButton
{
text
:
qsTr
(
"
Gimbal yaw
"
);
checked
:
true
;
enabled
:
false
}
QGCButton
{
text
:
qsTr
(
"
Rotate entry point
"
)
onClicked
:
missionItem
.
rotateEntryPoint
()
}
SectionHeader
{
id
:
statsHeader
text
:
qsTr
(
"
Statistics
"
)
}
Grid
{
columns
:
2
columnSpacing
:
ScreenTools
.
defaultFontPixelWidth
visible
:
statsHeader
.
checked
QGCLabel
{
text
:
qsTr
(
"
Photo count
"
)
}
QGCLabel
{
text
:
missionItem
.
cameraShots
}
QGCLabel
{
text
:
qsTr
(
"
Photo interval
"
)
}
QGCLabel
{
text
:
missionItem
.
timeBetweenShots
.
toFixed
(
1
)
+
"
"
+
qsTr
(
"
secs
"
)
}
}
}
}
src/PlanView/StructureScanMapVisual.qml
0 → 100644
View file @
801221a8
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
import
QtQuick
2.3
import
QtQuick
.
Controls
1.2
import
QtLocation
5.3
import
QtPositioning
5.3
import
QGroundControl
1.0
import
QGroundControl
.
ScreenTools
1.0
import
QGroundControl
.
Palette
1.0
import
QGroundControl
.
Controls
1.0
import
QGroundControl
.
FlightMap
1.0
/// Survey Complex Mission Item visuals
Item
{
id
:
_root
property
var
map
///< Map control to place item in
property
var
_missionItem
:
object
property
var
_mapPolygon
:
object
.
mapPolygon
property
var
_gridComponent
property
var
_entryCoordinate
property
var
_exitCoordinate
signal
clicked
(
int
sequenceNumber
)
function
_addVisualElements
()
{
_gridComponent
=
gridComponent
.
createObject
(
map
)
_entryCoordinate
=
entryPointComponent
.
createObject
(
map
)
_exitCoordinate
=
exitPointComponent
.
createObject
(
map
)
map
.
addMapItem
(
_gridComponent
)
map
.
addMapItem
(
_entryCoordinate
)
map
.
addMapItem
(
_exitCoordinate
)
}
function
_destroyVisualElements
()
{
_gridComponent
.
destroy
()
_entryCoordinate
.
destroy
()
_exitCoordinate
.
destroy
()
}
/// Add an initial 4 sided polygon if there is none
function
_addInitialPolygon
()
{
if
(
_mapPolygon
.
count
<
3
)
{
// Initial polygon is inset to take 2/3rds space
var
rect
=
Qt
.
rect
(
map
.
centerViewport
.
x
,
map
.
centerViewport
.
y
,
map
.
centerViewport
.
width
,
map
.
centerViewport
.
height
)
rect
.
x
+=
(
rect
.
width
*
0.25
)
/
2
rect
.
y
+=
(
rect
.
height
*
0.25
)
/
2
rect
.
width
*=
0.75
rect
.
height
*=
0.75
var
centerCoord
=
map
.
toCoordinate
(
Qt
.
point
(
rect
.
x
+
(
rect
.
width
/
2
),
rect
.
y
+
(
rect
.
height
/
2
)),
false
/* clipToViewPort */
)
var
topLeftCoord
=
map
.
toCoordinate
(
Qt
.
point
(
rect
.
x
,
rect
.
y
),
false
/* clipToViewPort */
)
var
topRightCoord
=
map
.
toCoordinate
(
Qt
.
point
(
rect
.
x
+
rect
.
width
,
rect
.
y
),
false
/* clipToViewPort */
)
var
bottomLeftCoord
=
map
.
toCoordinate
(
Qt
.
point
(
rect
.
x
,
rect
.
y
+
rect
.
height
),
false
/* clipToViewPort */
)
var
bottomRightCoord
=
map
.
toCoordinate
(
Qt
.
point
(
rect
.
x
+
rect
.
width
,
rect
.
y
+
rect
.
height
),
false
/* clipToViewPort */
)
// Initial polygon has max width and height of 3000 meters
var
halfWidthMeters
=
Math
.
min
(
topLeftCoord
.
distanceTo
(
topRightCoord
),
3000
)
/
2
var
halfHeightMeters
=
Math
.
min
(
topLeftCoord
.
distanceTo
(
bottomLeftCoord
),
3000
)
/
2
topLeftCoord
=
centerCoord
.
atDistanceAndAzimuth
(
halfWidthMeters
,
-
90
).
atDistanceAndAzimuth
(
halfHeightMeters
,
0
)
topRightCoord
=
centerCoord
.
atDistanceAndAzimuth
(
halfWidthMeters
,
90
).
atDistanceAndAzimuth
(
halfHeightMeters
,
0
)
bottomLeftCoord
=
centerCoord
.
atDistanceAndAzimuth
(
halfWidthMeters
,
-
90
).
atDistanceAndAzimuth
(
halfHeightMeters
,
180
)
bottomRightCoord
=
centerCoord
.
atDistanceAndAzimuth
(
halfWidthMeters
,
90
).
atDistanceAndAzimuth
(
halfHeightMeters
,
180
)
_mapPolygon
.
appendVertex
(
topLeftCoord
)
_mapPolygon
.
appendVertex
(
topRightCoord
)
_mapPolygon
.
appendVertex
(
bottomRightCoord
)
_mapPolygon
.
appendVertex
(
bottomLeftCoord
)
}
}
Component.onCompleted
:
{
_addInitialPolygon
()
_addVisualElements
()
}
Component.onDestruction
:
{
_destroyVisualElements
()
}
QGCMapPolygonVisuals
{
id
:
mapPolygonVisuals
mapControl
:
map
mapPolygon
:
_mapPolygon
interactive
:
_missionItem
.
isCurrentItem
borderWidth
:
1
borderColor
:
"
black
"
interiorColor
:
"
green
"
interiorOpacity
:
0.5
}
// Survey grid lines
Component
{
id
:
gridComponent
MapPolyline
{
line.color
:
"
white
"
line.width
:
2
path
:
_missionItem
.
gridPoints
}
}
// Entry point
Component
{
id
:
entryPointComponent
MapQuickItem
{
anchorPoint.x
:
sourceItem
.
anchorPointX
anchorPoint.y
:
sourceItem
.
anchorPointY
z
:
QGroundControl
.
zOrderMapItems
coordinate
:
_missionItem
.
coordinate
visible
:
_missionItem
.
exitCoordinate
.
isValid
sourceItem
:
MissionItemIndexLabel
{
index
:
_missionItem
.
sequenceNumber
label
:
"
Entry
"
checked
:
_missionItem
.
isCurrentItem
onClicked
:
_root
.
clicked
(
_missionItem
.
sequenceNumber
)
}
}
}
// Exit point
Component
{
id
:
exitPointComponent
MapQuickItem
{
anchorPoint.x
:
sourceItem
.
anchorPointX
anchorPoint.y
:
sourceItem
.
anchorPointY
z
:
QGroundControl
.
zOrderMapItems
coordinate
:
_missionItem
.
exitCoordinate
visible
:
_missionItem
.
exitCoordinate
.
isValid
sourceItem
:
MissionItemIndexLabel
{
index
:
_missionItem
.
lastSequenceNumber
label
:
"
Exit
"
checked
:
_missionItem
.
isCurrentItem
onClicked
:
_root
.
clicked
(
_missionItem
.
sequenceNumber
)
}
}
}
}
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