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
16505fd3
Commit
16505fd3
authored
Sep 01, 2016
by
Don Gagne
Committed by
GitHub
Sep 01, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3981 from wingtra/upstream/camera_survey
Camera survey enhancement with additional parameters
parents
d9fa1118
27146fa9
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
334 additions
and
58 deletions
+334
-58
SurveyItemEditor.qml
src/MissionEditor/SurveyItemEditor.qml
+327
-55
SurveyMissionItem.cc
src/MissionManager/SurveyMissionItem.cc
+7
-3
No files found.
src/MissionEditor/SurveyItemEditor.qml
View file @
16505fd3
import
QtQuick
2.2
import
QtQuick
.
Controls
1.2
import
QtQuick
.
Dialogs
1.2
import
QGroundControl
1.0
import
QGroundControl
.
ScreenTools
1.0
...
...
@@ -22,40 +23,128 @@ Rectangle {
property
real
_margin
:
ScreenTools
.
defaultFontPixelWidth
/
2
property
var
_cameraInfoCanonSX260
:
{
"
focalLength
"
:
4.5
,
"
sensorHeight
"
:
4.55
,
"
sensorWidth
"
:
6.17
}
property
int
cameraIndex
:
1
ListModel
{
id
:
cameraModelList
ListElement
{
text
:
qsTr
(
"
Custom
"
)
sensorWidth
:
0
sensorHeight
:
0
imageWidth
:
0
imageHeight
:
0
focalLength
:
0
}
ListElement
{
text
:
qsTr
(
"
Sony ILCE-QX1
"
)
//http://www.sony.co.uk/electronics/interchangeable-lens-cameras/ilce-qx1-body-kit/specifications
sensorWidth
:
23.2
//http://www.sony.com/electronics/camera-lenses/sel16f28/specifications
sensorHeight
:
15.4
imageWidth
:
5456
imageHeight
:
3632
focalLength
:
16
}
ListElement
{
text
:
qsTr
(
"
Canon S100 PowerShot
"
)
sensorWidth
:
7.6
sensorHeight
:
5.7
imageWidth
:
4000
imageHeight
:
3000
focalLength
:
5.2
}
ListElement
{
text
:
qsTr
(
"
Canon SX260 HS PowerShot
"
)
sensorWidth
:
6.17
sensorHeight
:
4.55
imageWidth
:
4000
imageHeight
:
3000
focalLength
:
4.5
}
}
function
recalcFromCameraValues
()
{
var
focalLength
=
Number
(
focalLengthField
.
text
)
var
sensorWidth
=
Number
(
sensorWidthField
.
text
)
var
sensorHeight
=
Number
(
sensorHeightField
.
text
)
var
overlap
=
Number
(
imageOverlapField
.
text
)
if
(
focalLength
<=
0.0
||
sensorWidth
<=
0.0
||
sensorHeight
<=
0.0
)
{
var
focalLength
=
cameraModelList
.
get
(
cameraIndex
).
focalLength
var
sensorWidth
=
cameraModelList
.
get
(
cameraIndex
).
sensorWidth
var
sensorHeight
=
cameraModelList
.
get
(
cameraIndex
).
sensorHeight
var
imageWidth
=
cameraModelList
.
get
(
cameraIndex
).
imageWidth
var
imageHeight
=
cameraModelList
.
get
(
cameraIndex
).
imageHeight
var
gsd
=
Number
(
gsdField
.
text
)
var
frontalOverlap
=
Number
(
frontalOverlapField
.
text
)
var
sideOverlap
=
Number
(
sideOverlapField
.
text
)
if
(
focalLength
<=
0.0
||
sensorWidth
<=
0.0
||
sensorHeight
<=
0.0
||
imageWidth
<
0
||
imageHeight
<
0
||
gsd
<
0.0
||
frontalOverlap
<
0
||
sideOverlap
<
0
)
{
missionItem
.
gridAltitude
.
rawValue
=
0
missionItem
.
gridSpacing
.
rawValue
=
0
missionItem
.
cameraTriggerDistance
.
rawValue
=
0
return
}
var
scaledFocalLengthMM
=
(
1000.0
*
missionItem
.
gridAltitude
.
rawValue
)
/
focalLength
var
imageWidthM
=
(
sensorWidth
*
scaledFocalLengthMM
)
/
1000.0
;
var
imageHeightM
=
(
sensorHeight
*
scaledFocalLengthMM
)
/
1000.0
;
var
altitude
var
imageSizeSideGround
//size in side (non flying) direction of the image on the ground
var
imageSizeFrontGround
//size in front (flying) direction of the image on the ground
var
gridSpacing
var
cameraTriggerDistance
altitude
=
(
imageWidth
*
gsd
*
focalLength
)
/
(
sensorWidth
*
100
)
if
(
cameraOrientationLandscape
.
checked
)
{
gridSpacing
=
imageWidthM
cameraTriggerDistance
=
imageHeightM
imageSizeSideGround
=
(
imageWidth
*
gsd
)
/
100
imageSizeFrontGround
=
(
imageHeight
*
gsd
)
/
100
}
else
{
gridSpacing
=
imageHeightM
cameraTriggerDistance
=
imageWidthM
imageSizeSideGround
=
(
imageHeight
*
gsd
)
/
100
imageSizeFrontGround
=
(
imageWidth
*
gsd
)
/
100
}
gridSpacing
=
(
1.0
-
(
overlap
/
100.0
))
*
gridSpacing
cameraTriggerDistance
=
(
1.0
-
(
overlap
/
100.0
))
*
cameraTriggerDistance
gridSpacing
=
imageSizeSideGround
*
(
(
100
-
sideOverlap
)
/
100
)
cameraTriggerDistance
=
imageSizeFrontGround
*
(
(
100
-
frontalOverlap
)
/
100
)
missionItem
.
gridAltitude
.
rawValue
=
altitude
missionItem
.
gridSpacing
.
rawValue
=
gridSpacing
missionItem
.
cameraTriggerDistance
.
rawValue
=
cameraTriggerDistance
}
function
recalcFromMissionValues
()
{
var
focalLength
=
cameraModelList
.
get
(
cameraIndex
).
focalLength
var
sensorWidth
=
cameraModelList
.
get
(
cameraIndex
).
sensorWidth
var
sensorHeight
=
cameraModelList
.
get
(
cameraIndex
).
sensorHeight
var
imageWidth
=
cameraModelList
.
get
(
cameraIndex
).
imageWidth
var
imageHeight
=
cameraModelList
.
get
(
cameraIndex
).
imageHeight
var
altitude
=
missionItem
.
gridAltitude
.
rawValue
var
gridSpacing
=
missionItem
.
gridSpacing
.
rawValue
var
cameraTriggerDistance
=
missionItem
.
cameraTriggerDistance
.
rawValue
if
(
focalLength
<=
0.0
||
sensorWidth
<=
0.0
||
sensorHeight
<=
0.0
||
imageWidth
<
0
||
imageHeight
<
0
||
altitude
<
0.0
||
gridSpacing
<
0.0
||
cameraTriggerDistance
<
0.0
)
{
gsdField
.
text
=
"
0.0
"
sideOverlapField
.
text
=
"
0
"
frontalOverlapField
.
text
=
"
0
"
return
}
var
gsd
var
imageSizeSideGround
//size in side (non flying) direction of the image on the ground
var
imageSizeFrontGround
//size in front (flying) direction of the image on the ground
gsd
=
(
altitude
*
sensorWidth
*
100
)
/
(
imageWidth
*
focalLength
)
if
(
cameraOrientationLandscape
.
checked
)
{
imageSizeSideGround
=
(
imageWidth
*
gsd
)
/
100
imageSizeFrontGround
=
(
imageHeight
*
gsd
)
/
100
}
else
{
imageSizeSideGround
=
(
imageHeight
*
gsd
)
/
100
imageSizeFrontGround
=
(
imageWidth
*
gsd
)
/
100
}
var
sideOverlap
=
(
imageSizeSideGround
==
0
?
0
:
100
-
(
gridSpacing
*
100
/
imageSizeSideGround
))
var
frontOverlap
=
(
imageSizeFrontGround
==
0
?
0
:
100
-
(
cameraTriggerDistance
*
100
/
imageSizeFrontGround
))
gsdField
.
text
=
gsd
.
toFixed
(
1
)
sideOverlapField
.
text
=
sideOverlap
.
toFixed
(
0
)
frontalOverlapField
.
text
=
frontOverlap
.
toFixed
(
0
)
}
function
polygonCaptureStarted
()
{
missionItem
.
clearPolygon
()
missionItem
.
clearPolygon
()
}
function
polygonCaptureFinished
(
coordinates
)
{
...
...
@@ -75,7 +164,9 @@ Rectangle {
ExclusiveGroup
{
id
:
cameraOrientationGroup
onCurrentChanged
:
recalcFromCameraValues
()
onCurrentChanged
:
{
recalcFromMissionValues
()
}
}
Column
{
...
...
@@ -112,6 +203,8 @@ Rectangle {
width
:
_editFieldWidth
showUnits
:
true
fact
:
modelData
onEditingFinished
:
recalcFromMissionValues
()
validator
:
DoubleValidator
{
bottom
:
0.0
;
decimals
:
2
}
}
}
}
...
...
@@ -123,6 +216,48 @@ Rectangle {
onClicked
:
missionItem
.
gridAltitudeRelative
=
checked
}
Grid
{
columns
:
2
columnSpacing
:
ScreenTools
.
defaultFontPixelWidth
rowSpacing
:
_margin
verticalItemAlignment
:
Grid
.
AlignVCenter
QGCLabel
{
text
:
qsTr
(
"
GSD:
"
)
width
:
_editFieldWidth
}
QGCTextField
{
id
:
gsdField
width
:
_editFieldWidth
unitsLabel
:
"
cm/px
"
showUnits
:
true
onEditingFinished
:
recalcFromCameraValues
()
validator
:
DoubleValidator
{
bottom
:
0.0
;
decimals
:
2
}
}
QGCLabel
{
text
:
qsTr
(
"
Frontal Overlap:
"
)
}
QGCTextField
{
id
:
frontalOverlapField
width
:
_editFieldWidth
unitsLabel
:
"
%
"
showUnits
:
true
onEditingFinished
:
recalcFromCameraValues
()
validator
:
IntValidator
{
bottom
:
0
}
}
QGCLabel
{
text
:
qsTr
(
"
Side Overlap:
"
)
}
QGCTextField
{
id
:
sideOverlapField
width
:
_editFieldWidth
unitsLabel
:
"
%
"
showUnits
:
true
onEditingFinished
:
recalcFromCameraValues
()
validator
:
IntValidator
{
bottom
:
0
}
}
Component.onCompleted
:
recalcFromMissionValues
()
}
QGCLabel
{
text
:
qsTr
(
"
Camera:
"
)
}
Rectangle
{
...
...
@@ -132,11 +267,14 @@ Rectangle {
color
:
qgcPal
.
text
}
Row
{
Grid
{
columns
:
2
spacing
:
ScreenTools
.
defaultFontPixelWidth
verticalItemAlignment
:
Grid
.
AlignVCenter
QGCRadioButton
{
id
:
cameraOrientationLandscape
width
:
_editFieldWidth
text
:
"
Landscape
"
checked
:
true
exclusiveGroup
:
cameraOrientationGroup
...
...
@@ -147,15 +285,10 @@ Rectangle {
text
:
"
Portrait
"
exclusiveGroup
:
cameraOrientationGroup
}
}
Grid
{
columns
:
2
spacing
:
ScreenTools
.
defaultFontPixelWidth
verticalItemAlignment
:
Grid
.
AlignVCenter
QGCCheckBox
{
id
:
cameraTrigger
width
:
_editFieldWidth
text
:
qsTr
(
"
Trigger:
"
)
checked
:
missionItem
.
cameraTrigger
onClicked
:
missionItem
.
cameraTrigger
=
checked
...
...
@@ -166,49 +299,188 @@ Rectangle {
showUnits
:
true
fact
:
missionItem
.
cameraTriggerDistance
enabled
:
missionItem
.
cameraTrigger
onEditingFinished
:
recalcFromMissionValues
()
validator
:
DoubleValidator
{
bottom
:
0.0
;
decimals
:
2
}
}
}
QGCLabel
{
text
:
qsTr
(
"
Focal length:
"
)
}
QGCTextField
{
id
:
focalLengthField
unitsLabel
:
"
mm
"
showUnits
:
true
text
:
_cameraInfoCanonSX260
.
focalLength
.
toString
()
Component
{
id
:
cameraFields
onEditingFinished
:
recalcFromCameraValues
()
}
QGCViewDialog
{
QGCLabel
{
text
:
qsTr
(
"
Sensor Width:
"
)
}
QGCTextField
{
id
:
sensorWidthField
unitsLabel
:
"
mm
"
showUnits
:
true
text
:
_cameraInfoCanonSX260
.
sensorWidth
.
toString
()
Column
{
id
:
dialogColumn
anchors.margins
:
_margin
anchors.top
:
parent
.
top
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
spacing
:
_margin
*
5
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
id
:
selectCameraModelText
text
:
qsTr
(
"
Select Camera Model:
"
)
}
QGCComboBox
{
id
:
cameraModelCombo
model
:
cameraModelList
width
:
dialogColumn
.
width
-
selectCameraModelText
.
width
-
ScreenTools
.
defaultFontPixelWidth
onActivated
:
{
cameraIndex
=
index
}
Component.onCompleted
:
{
var
index
=
cameraIndex
if
(
index
===
-
1
)
{
console
.
warn
(
"
Active camera model name not in combo
"
,
cameraIndex
)
}
else
{
cameraModelCombo
.
currentIndex
=
index
}
}
}
}
onEditingFinished
:
recalcFromCameraValues
()
Grid
{
columns
:
2
spacing
:
ScreenTools
.
defaultFontPixelWidth
verticalItemAlignment
:
Grid
.
AlignVCenter
QGCLabel
{
text
:
qsTr
(
"
Sensor Width:
"
)
}
QGCTextField
{
id
:
sensorWidthField
unitsLabel
:
"
mm
"
showUnits
:
true
text
:
cameraModelList
.
get
(
cameraIndex
).
sensorWidth
.
toFixed
(
2
)
readOnly
:
cameraIndex
!=
0
enabled
:
cameraIndex
==
0
validator
:
DoubleValidator
{
bottom
:
0.0
;
decimals
:
2
}
onEditingFinished
:
{
if
(
cameraIndex
==
0
)
{
cameraModelList
.
setProperty
(
cameraIndex
,
"
sensorWidth
"
,
Number
(
text
))
}
}
}
QGCLabel
{
text
:
qsTr
(
"
Sensor Height:
"
)
}
QGCTextField
{
id
:
sensorHeightField
unitsLabel
:
"
mm
"
showUnits
:
true
text
:
cameraModelList
.
get
(
cameraIndex
).
sensorHeight
.
toFixed
(
2
)
readOnly
:
cameraIndex
!=
0
enabled
:
cameraIndex
==
0
validator
:
DoubleValidator
{
bottom
:
0.0
;
decimals
:
2
}
onEditingFinished
:
{
if
(
cameraIndex
==
0
)
{
cameraModelList
.
setProperty
(
cameraIndex
,
"
sensorHeight
"
,
Number
(
text
))
}
}
}
QGCLabel
{
text
:
qsTr
(
"
Image Width:
"
)
}
QGCTextField
{
id
:
imageWidthField
unitsLabel
:
"
px
"
showUnits
:
true
text
:
cameraModelList
.
get
(
cameraIndex
).
imageWidth
.
toFixed
(
0
)
readOnly
:
cameraIndex
!=
0
enabled
:
cameraIndex
==
0
validator
:
IntValidator
{
bottom
:
0
}
onEditingFinished
:
{
if
(
cameraIndex
==
0
)
{
cameraModelList
.
setProperty
(
cameraIndex
,
"
imageWidth
"
,
Number
(
text
))
}
}
}
QGCLabel
{
text
:
qsTr
(
"
Image Height:
"
)
}
QGCTextField
{
id
:
imageHeightField
unitsLabel
:
"
px
"
showUnits
:
true
text
:
cameraModelList
.
get
(
cameraIndex
).
imageHeight
.
toFixed
(
0
)
readOnly
:
cameraIndex
!=
0
enabled
:
cameraIndex
==
0
validator
:
IntValidator
{
bottom
:
0
}
onEditingFinished
:
{
if
(
cameraIndex
==
0
)
{
cameraModelList
.
setProperty
(
cameraIndex
,
"
imageHeight
"
,
Number
(
text
))
}
}
}
QGCLabel
{
text
:
qsTr
(
"
Focal Length:
"
)
}
QGCTextField
{
id
:
focalLengthField
unitsLabel
:
"
mm
"
showUnits
:
true
text
:
cameraModelList
.
get
(
cameraIndex
).
focalLength
.
toFixed
(
2
)
readOnly
:
cameraIndex
!=
0
enabled
:
cameraIndex
==
0
validator
:
DoubleValidator
{
bottom
:
0.0
;
decimals
:
2
}
onEditingFinished
:
{
if
(
cameraIndex
==
0
)
{
cameraModelList
.
setProperty
(
cameraIndex
,
"
focalLength
"
,
Number
(
text
))
}
}
}
}
}
function
accept
()
{
hideDialog
()
recalcFromCameraValues
()
}
}
//QGCViewDialog
}
//Component
Column
{
spacing
:
ScreenTools
.
defaultFontPixelHeight
*
0.01
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
text
:
qsTr
(
"
Model:
"
)
}
QGCLabel
{
text
:
cameraModelList
.
get
(
cameraIndex
).
text
}
}
QGCLabel
{
text
:
qsTr
(
"
Sensor height:
"
)
}
QGCTextField
{
id
:
sensorHeightField
unitsLabel
:
"
mm
"
showUnits
:
true
text
:
_cameraInfoCanonSX260
.
sensorHeight
.
toString
()
Grid
{
columns
:
2
columnSpacing
:
ScreenTools
.
defaultFontPixelWidth
rowSpacing
:
ScreenTools
.
defaultFontPixelHeight
*
0.01
onEditingFinished
:
recalcFromCameraValues
()
QGCLabel
{
text
:
qsTr
(
"
Sensor Size:
"
)
width
:
_editFieldWidth
}
QGCLabel
{
text
:
cameraModelList
.
get
(
cameraIndex
).
sensorWidth
.
toFixed
(
2
)
+
qsTr
(
"
x
"
)
+
cameraModelList
.
get
(
cameraIndex
).
sensorHeight
.
toFixed
(
2
)
width
:
_editFieldWidth
}
QGCLabel
{
text
:
qsTr
(
"
Image Size:
"
)
}
QGCLabel
{
text
:
cameraModelList
.
get
(
cameraIndex
).
imageWidth
.
toFixed
(
0
)
+
qsTr
(
"
x
"
)
+
cameraModelList
.
get
(
cameraIndex
).
imageHeight
.
toFixed
(
0
)
}
QGCLabel
{
text
:
qsTr
(
"
Focal length:
"
)
}
QGCLabel
{
text
:
cameraModelList
.
get
(
cameraIndex
).
focalLength
.
toFixed
(
2
)
}
}
}
QGCLabel
{
text
:
qsTr
(
"
Image overlap:
"
)
}
QGCTextField
{
id
:
imageOverlapField
unitsLabel
:
"
%
"
showUnits
:
true
text
:
"
0
"
QGCButton
{
id
:
cameraModelChange
text
:
qsTr
(
"
Change
"
)
onEditingFinished
:
recalcFromCameraValues
()
onClicked
:
{
qgcView
.
showDialog
(
cameraFields
,
qsTr
(
"
Set Camera Model
"
),
qgcView
.
showDialogDefaultWidth
,
StandardButton
.
Save
)
}
}
QGCLabel
{
text
:
qsTr
(
"
Polygon:
"
)
}
Rectangle
{
...
...
src/MissionManager/SurveyMissionItem.cc
View file @
16505fd3
...
...
@@ -53,7 +53,7 @@ SurveyMissionItem::SurveyMissionItem(Vehicle* vehicle, QObject* parent)
,
_turnaroundDistMetaData
(
FactMetaData
::
valueTypeDouble
)
,
_cameraTriggerDistanceMetaData
(
FactMetaData
::
valueTypeDouble
)
{
_gridAltitudeFact
.
setRawValue
(
25
);
_gridAltitudeFact
.
setRawValue
(
50
);
_gridSpacingFact
.
setRawValue
(
10
);
_turnaroundDistFact
.
setRawValue
(
60
);
_cameraTriggerDistanceFact
.
setRawValue
(
25
);
...
...
@@ -344,7 +344,7 @@ void SurveyMissionItem::_clearGrid(void)
void
SurveyMissionItem
::
_generateGrid
(
void
)
{
if
(
_polygonPath
.
count
()
<
3
)
{
if
(
_polygonPath
.
count
()
<
3
||
_gridSpacingFact
.
rawValue
().
toDouble
()
<=
0
)
{
_clearGrid
();
return
;
}
...
...
@@ -391,7 +391,11 @@ void SurveyMissionItem::_generateGrid(void)
_gridPoints
+=
QVariant
::
fromValue
(
geoCoord
);
}
_setSurveyDistance
(
surveyDistance
);
_setCameraShots
((
int
)
floor
(
surveyDistance
/
_cameraTriggerDistanceFact
.
rawValue
().
toDouble
()));
if
(
_cameraTriggerDistanceFact
.
rawValue
().
toDouble
()
>
0
)
{
_setCameraShots
((
int
)
floor
(
surveyDistance
/
_cameraTriggerDistanceFact
.
rawValue
().
toDouble
()));
}
else
{
_setCameraShots
(
0
);
}
emit
gridPointsChanged
();
emit
lastSequenceNumberChanged
(
lastSequenceNumber
());
...
...
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