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
b37dda84
Commit
b37dda84
authored
Jun 26, 2019
by
Valentin Platzgummer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
editing WimaController ofter repurposeing
parent
c878bb8a
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
774 additions
and
527 deletions
+774
-527
WimaController.cc
src/Wima/WimaController.cc
+5
-481
WimaController.h
src/Wima/WimaController.h
+17
-39
WimaDataContainer.cc
src/Wima/WimaDataContainer.cc
+9
-0
WimaDataContainer.h
src/Wima/WimaDataContainer.h
+4
-0
WimaPlaner.cc
src/Wima/WimaPlaner.cc
+610
-1
WimaPlaner.h
src/Wima/WimaPlaner.h
+129
-6
No files found.
src/Wima/WimaController.cc
View file @
b37dda84
...
...
@@ -7,14 +7,13 @@ const char* WimaController::missionItemsName = "MissionItems";
WimaController
::
WimaController
(
QObject
*
parent
)
:
QObject
(
parent
)
,
_readyForSaveSend
(
false
)
,
_currentPolygonIndex
(
-
1
)
,
_container
(
nullptr
)
,
_joinedArea
(
this
)
,
_opArea
(
this
)
,
_serArea
(
this
)
,
_corridor
(
this
)
{
connect
(
this
,
&
WimaController
::
currentPolygonIndexChanged
,
this
,
&
WimaController
::
recalcPolygonInteractivity
);
}
QmlObjectListModel
*
WimaController
::
visualItems
()
...
...
@@ -44,7 +43,7 @@ QGeoCoordinate WimaController::joinedAreaCenter() const
return
_joinedArea
.
center
();
}
WimaArea
WimaController
::
joinedArea
()
const
QGCMapPolygon
WimaController
::
joinedArea
()
const
{
return
_joinedArea
;
}
...
...
@@ -61,19 +60,11 @@ void WimaController::setMissionController(MissionController *missionC)
emit
missionControllerChanged
();
}
void
WimaController
::
setCurrentPolygonIndex
(
int
index
)
{
if
(
index
>=
0
&&
index
<
_visualItems
.
count
()
&&
index
!=
_currentPolygonIndex
){
_currentPolygonIndex
=
index
;
emit
currentPolygonIndexChanged
(
index
);
}
}
void
WimaController
::
setDataContainer
(
WimaDataContainer
*
container
)
{
if
(
_container
==
nullptr
&&
container
!=
nullptr
)
{
_container
=
container
;
pullFromContainer
();
emit
dataContainerChanged
();
}
...
...
@@ -84,99 +75,6 @@ void WimaController::startWimaController(bool flyView)
}
void
WimaController
::
removeArea
(
int
index
)
{
if
(
index
>=
0
&&
index
<
_visualItems
.
count
()){
WimaArea
*
area
=
qobject_cast
<
WimaArea
*>
(
_visualItems
.
removeAt
(
index
));
if
(
area
==
nullptr
)
{
qWarning
(
"WimaController::removeArea(): nullptr catched, internal error."
);
return
;
}
area
->
clear
();
emit
visualItemsChanged
();
if
(
_visualItems
.
count
()
==
0
)
{
// this branch is reached if all items are removed
// to guarentee proper behavior, _currentPolygonIndex must be set to a invalid value, as on constructor init.
_currentPolygonIndex
=
-
1
;
return
;
}
if
(
_currentPolygonIndex
>=
_visualItems
.
count
()){
setCurrentPolygonIndex
(
_visualItems
.
count
()
-
1
);
}
else
{
recalcPolygonInteractivity
(
_currentPolygonIndex
);
}
}
else
{
qWarning
(
"Index out of bounds!"
);
}
}
bool
WimaController
::
addGOperationArea
()
{
if
(
!
_visualItems
.
contains
(
&
_opArea
))
{
_visualItems
.
append
(
&
_opArea
);
int
newIndex
=
_visualItems
.
count
()
-
1
;
setCurrentPolygonIndex
(
newIndex
);
emit
visualItemsChanged
();
return
true
;
}
else
{
return
false
;
}
}
bool
WimaController
::
addServiceArea
()
{
if
(
!
_visualItems
.
contains
(
&
_serArea
))
{
_visualItems
.
append
(
&
_serArea
);
int
newIndex
=
_visualItems
.
count
()
-
1
;
setCurrentPolygonIndex
(
newIndex
);
emit
visualItemsChanged
();
return
true
;
}
else
{
return
false
;
}
}
bool
WimaController
::
addVehicleCorridor
()
{
if
(
!
_visualItems
.
contains
(
&
_corridor
))
{
_visualItems
.
append
(
&
_corridor
);
int
newIndex
=
_visualItems
.
count
()
-
1
;
setCurrentPolygonIndex
(
newIndex
);
emit
visualItemsChanged
();
return
true
;
}
else
{
return
false
;
}
}
void
WimaController
::
removeAll
()
{
bool
changesApplied
=
false
;
while
(
_visualItems
.
count
()
>
0
)
{
removeArea
(
0
);
changesApplied
=
true
;
}
_missionController
->
removeAll
();
_currentFile
=
""
;
emit
currentFileChanged
();
if
(
changesApplied
)
emit
visualItemsChanged
();
}
void
WimaController
::
startMission
()
{
...
...
@@ -199,407 +97,33 @@ void WimaController::resumeMission()
bool
WimaController
::
updateMission
()
{
setReadyForSaveSend
(
false
);
#define debug 0
if
(
!
recalcJoinedArea
())
{
qgcApp
()
->
showMessage
(
tr
(
"Not able to join areas. Areas must be overlapping"
));
return
false
;
}
#if debug
_visualItems
.
append
(
&
_joinedArea
);
#endif
// reset visual items
_missionController
->
removeAll
();
QmlObjectListModel
*
missionItems
=
_missionController
->
visualItems
();
// set home position to serArea center
MissionSettingsItem
*
settingsItem
=
qobject_cast
<
MissionSettingsItem
*>
(
missionItems
->
get
(
0
));
if
(
settingsItem
==
nullptr
){
qWarning
(
"WimaController::updateMission(): settingsItem == nullptr"
);
return
false
;
}
// set altitudes, temporary measure to solve bugs
QGeoCoordinate
center
=
_serArea
.
center
();
center
.
setAltitude
(
0
);
_serArea
.
setCenter
(
center
);
center
=
_opArea
.
center
();
center
.
setAltitude
(
0
);
_opArea
.
setCenter
(
center
);
center
=
_corridor
.
center
();
center
.
setAltitude
(
0
);
_corridor
.
setCenter
(
center
);
// set HomePos. to serArea center
settingsItem
->
setCoordinate
(
_serArea
.
center
());
// create take off position item
int
sequenceNumber
=
_missionController
->
insertSimpleMissionItem
(
_serArea
.
center
(),
missionItems
->
count
());
_missionController
->
setCurrentPlanViewIndex
(
sequenceNumber
,
true
);
// create survey item, will be extened with more()-> mission types in the future
_missionController
->
insertComplexMissionItem
(
_missionController
->
surveyComplexItemName
(),
_opArea
.
center
(),
missionItems
->
count
());
SurveyComplexItem
*
survey
=
qobject_cast
<
SurveyComplexItem
*>
(
missionItems
->
get
(
missionItems
->
count
()
-
1
));
if
(
survey
==
nullptr
){
qWarning
(
"WimaController::updateMission(): survey == nullptr"
);
return
false
;
}
else
{
survey
->
surveyAreaPolygon
()
->
clear
();
survey
->
surveyAreaPolygon
()
->
appendVertices
(
_opArea
.
coordinateList
());
//survey->
}
// calculate path from take off to opArea
QGeoCoordinate
start
=
_serArea
.
center
();
QGeoCoordinate
end
=
survey
->
visualTransectPoints
().
first
().
value
<
QGeoCoordinate
>
();
QList
<
QGeoCoordinate
>
path
;
if
(
!
WimaArea
::
dijkstraPath
(
start
,
end
,
_joinedArea
,
path
))
{
qgcApp
()
->
showMessage
(
tr
(
"Not able to calculate the path from takeoff position to measurement area."
));
return
false
;
}
for
(
int
i
=
1
;
i
<
path
.
count
()
-
1
;
i
++
)
{
sequenceNumber
=
_missionController
->
insertSimpleMissionItem
(
path
.
value
(
i
),
missionItems
->
count
()
-
1
);
_missionController
->
setCurrentPlanViewIndex
(
sequenceNumber
,
true
);
}
// calculate return path
start
=
survey
->
visualTransectPoints
().
last
().
value
<
QGeoCoordinate
>
();
end
=
_serArea
.
center
();
path
.
clear
();
if
(
!
WimaArea
::
dijkstraPath
(
start
,
end
,
_joinedArea
,
path
))
{
qgcApp
()
->
showMessage
(
tr
(
"Not able to calculate the path from measurement area to landing position."
));
return
false
;
}
for
(
int
i
=
1
;
i
<
path
.
count
()
-
1
;
i
++
)
{
sequenceNumber
=
_missionController
->
insertSimpleMissionItem
(
path
.
value
(
i
),
missionItems
->
count
());
_missionController
->
setCurrentPlanViewIndex
(
sequenceNumber
,
true
);
}
// create land position item
sequenceNumber
=
_missionController
->
insertSimpleMissionItem
(
_serArea
.
center
(),
missionItems
->
count
());
_missionController
->
setCurrentPlanViewIndex
(
sequenceNumber
,
true
);
SimpleMissionItem
*
landItem
=
qobject_cast
<
SimpleMissionItem
*>
(
missionItems
->
get
(
missionItems
->
count
()
-
1
));
if
(
landItem
==
nullptr
){
qWarning
(
"WimaController::updateMission(): landItem == nullptr"
);
return
false
;
}
else
{
Vehicle
*
controllerVehicle
=
_masterController
->
controllerVehicle
();
MAV_CMD
landCmd
=
controllerVehicle
->
vtol
()
?
MAV_CMD_NAV_VTOL_LAND
:
MAV_CMD_NAV_LAND
;
if
(
controllerVehicle
->
firmwarePlugin
()
->
supportedMissionCommands
().
contains
(
landCmd
))
{
landItem
->
setCommand
(
landCmd
);
}
}
updateContainer
();
setReadyForSaveSend
(
true
);
return
true
;
}
void
WimaController
::
saveToCurrent
()
{
saveToFile
(
_currentFile
);
}
void
WimaController
::
saveToFile
(
const
QString
&
filename
)
{
if
(
filename
.
isEmpty
())
{
return
;
}
QString
planFilename
=
filename
;
if
(
!
QFileInfo
(
filename
).
fileName
().
contains
(
"."
))
{
planFilename
+=
QString
(
".%1"
).
arg
(
wimaFileExtension
);
}
QFile
file
(
planFilename
);
if
(
!
file
.
open
(
QIODevice
::
WriteOnly
|
QIODevice
::
Text
))
{
qgcApp
()
->
showMessage
(
tr
(
"Plan save error %1 : %2"
).
arg
(
filename
).
arg
(
file
.
errorString
()));
_currentFile
.
clear
();
emit
currentFileChanged
();
}
else
{
FileType
fileType
=
FileType
::
WimaFile
;
if
(
planFilename
.
contains
(
QString
(
".%1"
).
arg
(
wimaFileExtension
))
)
{
fileType
=
FileType
::
WimaFile
;
}
else
if
(
planFilename
.
contains
(
QString
(
".%1"
).
arg
(
AppSettings
::
planFileExtension
))
)
{
fileType
=
FileType
::
PlanFile
;
}
else
{
if
(
planFilename
.
contains
(
"."
)
)
{
qgcApp
()
->
showMessage
(
tr
(
"File format not supported"
));
}
else
{
qgcApp
()
->
showMessage
(
tr
(
"File without file extension not accepted."
));
return
;
}
}
QJsonDocument
saveDoc
=
saveToJson
(
fileType
);
file
.
write
(
saveDoc
.
toJson
());
if
(
_currentFile
!=
planFilename
)
{
_currentFile
=
planFilename
;
emit
currentFileChanged
();
}
}
}
bool
WimaController
::
loadFromCurrent
()
{
return
loadFromFile
(
_currentFile
)
;
return
true
;
}
bool
WimaController
::
loadFromFile
(
const
QString
&
filename
)
{
#define debug 0
QString
errorString
;
QString
errorMessage
=
tr
(
"Error loading Plan file (%1). %2"
).
arg
(
filename
).
arg
(
"%1"
);
if
(
filename
.
isEmpty
())
{
return
false
;
}
QFileInfo
fileInfo
(
filename
);
QFile
file
(
filename
);
if
(
!
file
.
open
(
QIODevice
::
ReadOnly
|
QIODevice
::
Text
))
{
errorString
=
file
.
errorString
()
+
QStringLiteral
(
" "
)
+
filename
;
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
if
(
fileInfo
.
suffix
()
==
wimaFileExtension
)
{
QJsonDocument
jsonDoc
;
QByteArray
bytes
=
file
.
readAll
();
if
(
!
JsonHelper
::
isJsonFile
(
bytes
,
jsonDoc
,
errorString
))
{
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
QJsonObject
json
=
jsonDoc
.
object
();
// AreaItems
QJsonArray
areaArray
=
json
[
areaItemsName
].
toArray
();
_visualItems
.
clear
();
int
validAreaCounter
=
0
;
for
(
int
i
=
0
;
i
<
areaArray
.
size
()
&&
validAreaCounter
<
3
;
i
++
)
{
QJsonObject
jsonArea
=
areaArray
[
i
].
toObject
();
if
(
jsonArea
.
contains
(
WimaArea
::
areaTypeName
)
&&
jsonArea
[
WimaArea
::
areaTypeName
].
isString
())
{
if
(
jsonArea
[
WimaArea
::
areaTypeName
]
==
WimaGOperationArea
::
wimaGOperationAreaName
)
{
print
(
_opArea
);
bool
success
=
_opArea
.
loadFromJson
(
jsonArea
,
errorString
);
print
(
_opArea
);
if
(
!
success
)
{
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
validAreaCounter
++
;
_visualItems
.
append
(
&
_opArea
);
emit
visualItemsChanged
();
}
else
if
(
jsonArea
[
WimaArea
::
areaTypeName
]
==
WimaServiceArea
::
wimaServiceAreaName
)
{
bool
success
=
_serArea
.
loadFromJson
(
jsonArea
,
errorString
);
if
(
!
success
)
{
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
validAreaCounter
++
;
_visualItems
.
append
(
&
_serArea
);
emit
visualItemsChanged
();
}
else
if
(
jsonArea
[
WimaArea
::
areaTypeName
]
==
WimaVCorridor
::
wimaVCorridorName
)
{
bool
success
=
_corridor
.
loadFromJson
(
jsonArea
,
errorString
);
if
(
!
success
)
{
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
validAreaCounter
++
;
_visualItems
.
append
(
&
_corridor
);
emit
visualItemsChanged
();
}
else
{
errorString
+=
QString
(
tr
(
"%s not supported.
\n
"
).
arg
(
WimaArea
::
areaTypeName
));
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
}
else
{
errorString
+=
QString
(
tr
(
"Invalid or non existing entry for %s.
\n
"
).
arg
(
WimaArea
::
areaTypeName
));
return
false
;
}
}
_currentFile
.
sprintf
(
"%s/%s.%s"
,
fileInfo
.
path
().
toLocal8Bit
().
data
(),
fileInfo
.
completeBaseName
().
toLocal8Bit
().
data
(),
wimaFileExtension
);
emit
currentFileChanged
();
recalcJoinedArea
();
// MissionItems
// extrac MissionItems part
QJsonDocument
missionJsonDoc
=
QJsonDocument
(
json
[
missionItemsName
].
toObject
());
// create temporary file with missionItems
QFile
temporaryFile
;
QString
cropedFileName
=
filename
.
section
(
"/"
,
0
,
-
2
);
#if debug
qWarning
()
<<
cropedFileName
;
#endif
QString
temporaryFileName
;
for
(
int
i
=
0
;
;
i
++
)
{
temporaryFileName
=
cropedFileName
.
append
(
"/temp%1.%2"
).
arg
(
i
).
arg
(
AppSettings
::
planFileExtension
);
if
(
!
QFile
::
exists
(
temporaryFileName
)
)
{
temporaryFile
.
setFileName
(
temporaryFileName
);
if
(
temporaryFile
.
open
(
QIODevice
::
WriteOnly
|
QIODevice
::
Text
)
)
{
break
;
}
}
if
(
i
>
1000
)
{
qWarning
(
"WimaController::loadFromFile(): not able to create temporary file."
);
return
false
;
}
}
temporaryFile
.
write
(
missionJsonDoc
.
toJson
());
// load from temporary file
_masterController
->
loadFromFile
(
temporaryFileName
);
// remove temporary file
if
(
!
temporaryFile
.
remove
()
){
qWarning
(
"WimaController::loadFromFile(): not able to remove temporary file."
);
}
return
true
;
}
else
if
(
fileInfo
.
suffix
()
==
AppSettings
::
planFileExtension
){
_masterController
->
loadFromFile
(
filename
);
return
true
;
// might be wrong return value
}
else
{
errorString
+=
QString
(
tr
(
"File extension not supported.
\n
"
));
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
}
void
WimaController
::
recalcPolygonInteractivity
(
int
index
)
{
if
(
index
>=
0
&&
index
<
_visualItems
.
count
())
{
resetAllInteractive
();
WimaArea
*
interactivePoly
=
qobject_cast
<
WimaArea
*>
(
_visualItems
.
get
(
index
));
interactivePoly
->
setInteractive
(
true
);
}
}
bool
WimaController
::
recalcJoinedArea
()
{
// join service area, op area and corridor
_joinedArea
=
_serArea
;
_joinedArea
.
join
(
_corridor
);
if
(
!
_joinedArea
.
join
(
_opArea
)
)
return
false
;
// this happens if all areas are pairwise disjoint
else
{
emit
joinedAreaChanged
()
;
return
true
;
}
}
void
WimaController
::
updateContainer
()
{
// Sets the pointers (inside _container) to the areas (of this).
// Should be called only (once) after a _container has been assigned.
if
(
_container
!=
nullptr
)
{
_container
->
setOpArea
(
&
_opArea
);
_container
->
setSerArea
(
&
_serArea
);
_container
->
setCorridor
(
&
_corridor
);
_container
->
setJoinedArea
(
&
_joinedArea
);
}
else
{
qWarning
(
"WimaController::uploadToContainer(): no container assigned."
);
}
return
true
;
}
void
WimaController
::
resetAllInteractive
()
{
// Marks all areas as inactive (area.interactive == false)
int
itemCount
=
_visualItems
.
count
();
if
(
itemCount
>
0
){
for
(
int
i
=
0
;
i
<
itemCount
;
i
++
)
{
WimaArea
*
iteratorPoly
=
qobject_cast
<
WimaArea
*>
(
_visualItems
.
get
(
i
));
iteratorPoly
->
setInteractive
(
false
);
}
}
}
void
WimaController
::
setInteractive
()
{
recalcPolygonInteractivity
(
_currentPolygonIndex
);
}
QJsonDocument
WimaController
::
saveToJson
(
FileType
fileType
)
{
/// This function save all areas (of WimaController) and all mission items (of MissionController) to a QJsonDocument
/// @param fileType is either WimaFile or PlanFile (enum), if fileType == PlanFile only mission items are stored
QJsonObject
json
;
if
(
fileType
==
FileType
::
WimaFile
)
{
QJsonArray
jsonArray
;
for
(
int
i
=
0
;
i
<
_visualItems
.
count
();
i
++
)
{
QJsonObject
json
;
WimaArea
*
area
=
qobject_cast
<
WimaArea
*>
(
_visualItems
.
get
(
i
));
if
(
area
==
nullptr
)
{
qWarning
(
"WimaController::saveToJson(): Internal error, area == nullptr!"
);
return
QJsonDocument
();
}
// check the type of area, create and append the JsonObject to the JsonArray once determined
WimaGOperationArea
*
opArea
=
qobject_cast
<
WimaGOperationArea
*>
(
area
);
if
(
opArea
!=
nullptr
)
{
opArea
->
saveToJson
(
json
);
jsonArray
.
append
(
json
);
continue
;
}
WimaServiceArea
*
serArea
=
qobject_cast
<
WimaServiceArea
*>
(
area
);
if
(
serArea
!=
nullptr
)
{
serArea
->
saveToJson
(
json
);
jsonArray
.
append
(
json
);
continue
;
}
WimaVCorridor
*
corridor
=
qobject_cast
<
WimaVCorridor
*>
(
area
);
if
(
corridor
!=
nullptr
)
{
corridor
->
saveToJson
(
json
);
jsonArray
.
append
(
json
);
continue
;
}
// if non of the obove branches was trigger, type must be WimaArea
area
->
saveToJson
(
json
);
jsonArray
.
append
(
json
);
}
json
[
areaItemsName
]
=
jsonArray
;
json
[
missionItemsName
]
=
_masterController
->
saveToJson
().
object
();
return
QJsonDocument
(
json
);
}
else
if
(
fileType
==
FileType
::
PlanFile
)
{
return
_masterController
->
saveToJson
();
}
return
QJsonDocument
(
json
);
}
void
WimaController
::
setReadyForSaveSend
(
bool
ready
)
...
...
src/Wima/WimaController.h
View file @
b37dda84
...
...
@@ -32,14 +32,12 @@ public:
Q_PROPERTY
(
PlanMasterController
*
masterController
READ
masterController
WRITE
setMasterController
NOTIFY
masterControllerChanged
)
Q_PROPERTY
(
MissionController
*
missionController
READ
missionController
WRITE
setMissionController
NOTIFY
missionControllerChanged
)
Q_PROPERTY
(
QmlObjectListModel
*
visualItems
READ
visualItems
NOTIFY
visualItemsChanged
)
Q_PROPERTY
(
int
currentPolygonIndex
READ
currentPolygonIndex
WRITE
setCurrentPolygonIndex
NOTIFY
currentPolygonIndexChanged
)
Q_PROPERTY
(
QString
currentFile
READ
currentFile
NOTIFY
currentFileChanged
)
Q_PROPERTY
(
QStringList
loadNameFilters
READ
loadNameFilters
CONSTANT
)
Q_PROPERTY
(
QStringList
saveNameFilters
READ
saveNameFilters
CONSTANT
)
Q_PROPERTY
(
QString
fileExtension
READ
fileExtension
CONSTANT
)
Q_PROPERTY
(
QGeoCoordinate
joinedAreaCenter
READ
joinedAreaCenter
CONSTANT
)
Q_PROPERTY
(
WimaArea
joinedArea
READ
joinedArea
NOTIFY
joinedAreaChanged
)
Q_PROPERTY
(
bool
flyView
READ
flyView
CONSTANT
)
Q_PROPERTY
(
WimaDataContainer
*
dataContainer
WRITE
setDataContainer
NOTIFY
dataContainerChanged
)
Q_PROPERTY
(
bool
readyForSaveSend
READ
readyForSaveSend
NOTIFY
readyForSaveSendChanged
)
...
...
@@ -48,13 +46,12 @@ public:
PlanMasterController
*
masterController
(
void
)
const
{
return
_masterController
;
}
MissionController
*
missionController
(
void
)
const
{
return
_missionController
;
}
QmlObjectListModel
*
visualItems
(
void
)
;
int
currentPolygonIndex
(
void
)
const
{
return
_currentPolygonIndex
;
}
QString
currentFile
(
void
)
const
{
return
_currentFile
;
}
QStringList
loadNameFilters
(
void
)
const
;
QStringList
saveNameFilters
(
void
)
const
;
QString
fileExtension
(
void
)
const
{
return
wimaFileExtension
;
}
QGeoCoordinate
joinedAreaCenter
(
void
)
const
;
WimaArea
joinedArea
(
void
)
const
;
QGCMapPolygon
joinedArea
(
void
)
const
;
bool
readyForSaveSend
(
void
)
const
{
return
_readyForSaveSend
;
}
...
...
@@ -62,35 +59,20 @@ public:
// Property setters
void
setMasterController
(
PlanMasterController
*
masterController
);
void
setMissionController
(
MissionController
*
missionController
);
/// Sets the integer index pointing to the current polygon. Current polygon is set interactive.
void
setCurrentPolygonIndex
(
int
index
);
void
setDataContainer
(
WimaDataContainer
*
container
);
// Member Methodes
Q_INVOKABLE
void
startWimaController
(
bool
flyView
);
Q_INVOKABLE
bool
addGOperationArea
();
/// Removes an area from _visualItems
/// @param index Index of the area to be removed
Q_INVOKABLE
void
removeArea
(
int
index
);
Q_INVOKABLE
bool
addServiceArea
();
Q_INVOKABLE
bool
addVehicleCorridor
();
/// Remove all areas from WimaController and all mission items from MissionController
Q_INVOKABLE
void
removeAll
();
Q_INVOKABLE
void
startMission
();
Q_INVOKABLE
void
abortMission
();
Q_INVOKABLE
void
pauseMission
();
Q_INVOKABLE
void
resumeMission
();
/// Recalculates vehicle corridor, flight path, etc.
Q_INVOKABLE
bool
updateMission
();
Q_INVOKABLE
void
saveToCurrent
();
Q_INVOKABLE
void
saveToFile
(
const
QString
&
filename
);
Q_INVOKABLE
void
saveToCurrent
();
Q_INVOKABLE
void
saveToFile
(
const
QString
&
filename
);
Q_INVOKABLE
bool
loadFromCurrent
();
Q_INVOKABLE
bool
loadFromFile
(
const
QString
&
filename
);
Q_INVOKABLE
void
resetAllInteractive
(
void
);
Q_INVOKABLE
void
setInteractive
(
void
);
Q_INVOKABLE
bool
loadFromFile
(
const
QString
&
filename
);
// static Members
...
...
@@ -102,32 +84,28 @@ public:
QJsonDocument
saveToJson
(
FileType
fileType
);
void
setReadyForSaveSend
(
bool
ready
);
signals:
void
masterControllerChanged
(
void
);
void
missionControllerChanged
(
void
);
void
visualItemsChanged
(
void
);
void
currentPolygonIndexChanged
(
int
index
);
void
currentFileChanged
();
void
joinedAreaChanged
();
void
dataContainerChanged
();
void
readyForSaveSendChanged
(
bool
ready
);
private
slots
:
void
recalcPolygonInteractivity
(
int
index
);
bool
recalcJoinedArea
();
void
updateContainer
();
// only executed if flyView == false
void
downloadFromContainer
();
// only executed if flyView == true
void
pullFromContainer
();
private:
bool
_readyForSaveSend
;
PlanMasterController
*
_masterController
;
MissionController
*
_missionController
;
int
_currentPolygonIndex
;
QString
_currentFile
;
WimaDataContainer
*
_container
;
QmlObjectListModel
_visualItems
;
WimaArea
_joinedArea
;
WimaGOperationArea
_opArea
;
WimaServiceArea
_serArea
;
WimaVCorridor
_corridor
;
bool
_readyForSaveSend
;
// basically true if updateMission() was sucessful
PlanMasterController
*
_masterController
;
MissionController
*
_missionController
;
QString
_currentFile
;
// file for saveing
WimaDataContainer
*
_container
;
// container for data exchange with WimaController
QmlObjectListModel
_visualItems
;
// contains all visible areas
// The following areas are of type QGCMapPolygon (only path information is required, as they are used for visualisation)
QGCMapPolygon
_joinedArea
;
// joined area fromed by opArea, serArea, _corridor
QGCMapPolygon
_opArea
;
// measurement area
QGCMapPolygon
_serArea
;
// area for supplying
QGCMapPolygon
_corridor
;
// corridor connecting opArea and serArea
};
src/Wima/WimaDataContainer.cc
View file @
b37dda84
...
...
@@ -45,3 +45,12 @@ void WimaDataContainer::setCorridor(const WimaVCorridor *corridor)
emit
corridorChanged
(
_corridor
);
}
}
void
WimaDataContainer
::
setVisualItems
(
const
QmlObjectListModel
*
visualItems
)
{
if
(
_visualItems
!=
visualItems
)
{
_visualItems
=
visualItems
;
emit
visualItemsChanged
(
_visualItems
);
}
}
src/Wima/WimaDataContainer.h
View file @
b37dda84
...
...
@@ -21,23 +21,27 @@ public:
const
WimaGOperationArea
*
opArea
(
void
)
{
return
_opArea
;
}
const
WimaServiceArea
*
serArea
(
void
)
{
return
_serArea
;
}
const
WimaVCorridor
*
corridor
(
void
)
{
return
_corridor
;
}
const
QmlObjectListModel
*
visualItems
(
void
)
{
return
_visualItems
;
}
signals:
void
joinedAreaChanged
(
const
WimaArea
*
area
);
void
opAreaChanged
(
const
WimaGOperationArea
*
area
);
void
serAreaChanged
(
const
WimaServiceArea
*
area
);
void
corridorChanged
(
const
WimaVCorridor
*
area
);
void
visualItemsChanged
(
const
QmlObjectListModel
*
area
);
public
slots
:
void
setJoinedArea
(
const
WimaArea
*
joinedArea
);
void
setOpArea
(
const
WimaGOperationArea
*
opArea
);
void
setSerArea
(
const
WimaServiceArea
*
serArea
);
void
setCorridor
(
const
WimaVCorridor
*
corridor
);
void
setVisualItems
(
const
QmlObjectListModel
*
visualItems
);
private:
const
WimaArea
*
_joinedArea
;
const
WimaGOperationArea
*
_opArea
;
const
WimaServiceArea
*
_serArea
;
const
WimaVCorridor
*
_corridor
;
const
QmlObjectListModel
*
_visualItems
;
};
src/Wima/WimaPlaner.cc
View file @
b37dda84
#include "WimaPlaner.h"
WimaPlaner
::
WimaPlaner
()
const
char
*
WimaPlaner
::
wimaFileExtension
=
"wima"
;
const
char
*
WimaPlaner
::
areaItemsName
=
"AreaItems"
;
const
char
*
WimaPlaner
::
missionItemsName
=
"MissionItems"
;
WimaPlaner
::
WimaPlaner
(
QObject
*
parent
)
:
QObject
(
parent
)
,
_readyForSaveSend
(
false
)
,
_currentAreaIndex
(
-
1
)
,
_container
(
nullptr
)
,
_joinedArea
(
this
)
,
_opArea
(
this
)
,
_serArea
(
this
)
,
_corridor
(
this
)
{
connect
(
this
,
&
WimaPlaner
::
currentPolygonIndexChanged
,
this
,
&
WimaPlaner
::
recalcPolygonInteractivity
);
}
QmlObjectListModel
*
WimaPlaner
::
visualItems
()
{
return
&
_visualItems
;
}
QStringList
WimaPlaner
::
loadNameFilters
()
const
{
QStringList
filters
;
filters
<<
tr
(
"Supported types (*.%1 *.%2)"
).
arg
(
wimaFileExtension
).
arg
(
AppSettings
::
planFileExtension
)
<<
tr
(
"All Files (*.*)"
);
return
filters
;
}
QStringList
WimaPlaner
::
saveNameFilters
()
const
{
QStringList
filters
;
filters
<<
tr
(
"Supported types (*.%1 *.%2)"
).
arg
(
wimaFileExtension
).
arg
(
AppSettings
::
planFileExtension
);
return
filters
;
}
QGeoCoordinate
WimaPlaner
::
joinedAreaCenter
()
const
{
return
_joinedArea
.
center
();
}
WimaArea
WimaPlaner
::
joinedArea
()
const
{
return
_joinedArea
;
}
void
WimaPlaner
::
setMasterController
(
PlanMasterController
*
masterC
)
{
_masterController
=
masterC
;
emit
masterControllerChanged
();
}
void
WimaPlaner
::
setMissionController
(
MissionController
*
missionC
)
{
_missionController
=
missionC
;
emit
missionControllerChanged
();
}
void
WimaPlaner
::
setCurrentPolygonIndex
(
int
index
)
{
if
(
index
>=
0
&&
index
<
_visualItems
.
count
()
&&
index
!=
_currentAreaIndex
){
_currentAreaIndex
=
index
;
emit
currentPolygonIndexChanged
(
index
);
}
}
void
WimaPlaner
::
setDataContainer
(
WimaDataContainer
*
container
)
{
if
(
_container
==
nullptr
&&
container
!=
nullptr
)
{
_container
=
container
;
emit
dataContainerChanged
();
}
}
void
WimaPlaner
::
startWimaPlaner
(
bool
flyView
)
{
}
void
WimaPlaner
::
removeArea
(
int
index
)
{
if
(
index
>=
0
&&
index
<
_visualItems
.
count
()){
WimaArea
*
area
=
qobject_cast
<
WimaArea
*>
(
_visualItems
.
removeAt
(
index
));
if
(
area
==
nullptr
)
{
qWarning
(
"WimaPlaner::removeArea(): nullptr catched, internal error."
);
return
;
}
area
->
clear
();
emit
visualItemsChanged
();
if
(
_visualItems
.
count
()
==
0
)
{
// this branch is reached if all items are removed
// to guarentee proper behavior, _currentAreaIndex must be set to a invalid value, as on constructor init.
_currentAreaIndex
=
-
1
;
return
;
}
if
(
_currentAreaIndex
>=
_visualItems
.
count
()){
setCurrentPolygonIndex
(
_visualItems
.
count
()
-
1
);
}
else
{
recalcPolygonInteractivity
(
_currentAreaIndex
);
}
}
else
{
qWarning
(
"Index out of bounds!"
);
}
}
bool
WimaPlaner
::
addGOperationArea
()
{
if
(
!
_visualItems
.
contains
(
&
_opArea
))
{
_visualItems
.
append
(
&
_opArea
);
int
newIndex
=
_visualItems
.
count
()
-
1
;
setCurrentPolygonIndex
(
newIndex
);
emit
visualItemsChanged
();
return
true
;
}
else
{
return
false
;
}
}
bool
WimaPlaner
::
addServiceArea
()
{
if
(
!
_visualItems
.
contains
(
&
_serArea
))
{
_visualItems
.
append
(
&
_serArea
);
int
newIndex
=
_visualItems
.
count
()
-
1
;
setCurrentPolygonIndex
(
newIndex
);
emit
visualItemsChanged
();
return
true
;
}
else
{
return
false
;
}
}
bool
WimaPlaner
::
addVehicleCorridor
()
{
if
(
!
_visualItems
.
contains
(
&
_corridor
))
{
_visualItems
.
append
(
&
_corridor
);
int
newIndex
=
_visualItems
.
count
()
-
1
;
setCurrentPolygonIndex
(
newIndex
);
emit
visualItemsChanged
();
return
true
;
}
else
{
return
false
;
}
}
void
WimaPlaner
::
removeAll
()
{
bool
changesApplied
=
false
;
while
(
_visualItems
.
count
()
>
0
)
{
removeArea
(
0
);
changesApplied
=
true
;
}
_missionController
->
removeAll
();
_currentFile
=
""
;
emit
currentFileChanged
();
if
(
changesApplied
)
emit
visualItemsChanged
();
}
void
WimaPlaner
::
startMission
()
{
}
void
WimaPlaner
::
abortMission
()
{
}
void
WimaPlaner
::
pauseMission
()
{
}
void
WimaPlaner
::
resumeMission
()
{
}
bool
WimaPlaner
::
updateMission
()
{
setReadyForSaveSend
(
false
);
#define debug 0
if
(
!
recalcJoinedArea
())
{
qgcApp
()
->
showMessage
(
tr
(
"Not able to join areas. Areas must be overlapping"
));
return
false
;
}
#if debug
_visualItems
.
append
(
&
_joinedArea
);
#endif
// reset visual items
_missionController
->
removeAll
();
QmlObjectListModel
*
missionItems
=
_missionController
->
visualItems
();
// set home position to serArea center
MissionSettingsItem
*
settingsItem
=
qobject_cast
<
MissionSettingsItem
*>
(
missionItems
->
get
(
0
));
if
(
settingsItem
==
nullptr
){
qWarning
(
"WimaPlaner::updateMission(): settingsItem == nullptr"
);
return
false
;
}
// set altitudes, temporary measure to solve bugs
QGeoCoordinate
center
=
_serArea
.
center
();
center
.
setAltitude
(
0
);
_serArea
.
setCenter
(
center
);
center
=
_opArea
.
center
();
center
.
setAltitude
(
0
);
_opArea
.
setCenter
(
center
);
center
=
_corridor
.
center
();
center
.
setAltitude
(
0
);
_corridor
.
setCenter
(
center
);
// set HomePos. to serArea center
settingsItem
->
setCoordinate
(
_serArea
.
center
());
// create take off position item
int
sequenceNumber
=
_missionController
->
insertSimpleMissionItem
(
_serArea
.
center
(),
missionItems
->
count
());
_missionController
->
setCurrentPlanViewIndex
(
sequenceNumber
,
true
);
// create survey item, will be extened with more()-> mission types in the future
_missionController
->
insertComplexMissionItem
(
_missionController
->
surveyComplexItemName
(),
_opArea
.
center
(),
missionItems
->
count
());
SurveyComplexItem
*
survey
=
qobject_cast
<
SurveyComplexItem
*>
(
missionItems
->
get
(
missionItems
->
count
()
-
1
));
if
(
survey
==
nullptr
){
qWarning
(
"WimaPlaner::updateMission(): survey == nullptr"
);
return
false
;
}
else
{
survey
->
surveyAreaPolygon
()
->
clear
();
survey
->
surveyAreaPolygon
()
->
appendVertices
(
_opArea
.
coordinateList
());
//survey->
}
// calculate path from take off to opArea
QGeoCoordinate
start
=
_serArea
.
center
();
QGeoCoordinate
end
=
survey
->
visualTransectPoints
().
first
().
value
<
QGeoCoordinate
>
();
QList
<
QGeoCoordinate
>
path
;
if
(
!
WimaArea
::
dijkstraPath
(
start
,
end
,
_joinedArea
,
path
))
{
qgcApp
()
->
showMessage
(
tr
(
"Not able to calculate the path from takeoff position to measurement area."
));
return
false
;
}
for
(
int
i
=
1
;
i
<
path
.
count
()
-
1
;
i
++
)
{
sequenceNumber
=
_missionController
->
insertSimpleMissionItem
(
path
.
value
(
i
),
missionItems
->
count
()
-
1
);
_missionController
->
setCurrentPlanViewIndex
(
sequenceNumber
,
true
);
}
// calculate return path
start
=
survey
->
visualTransectPoints
().
last
().
value
<
QGeoCoordinate
>
();
end
=
_serArea
.
center
();
path
.
clear
();
if
(
!
WimaArea
::
dijkstraPath
(
start
,
end
,
_joinedArea
,
path
))
{
qgcApp
()
->
showMessage
(
tr
(
"Not able to calculate the path from measurement area to landing position."
));
return
false
;
}
for
(
int
i
=
1
;
i
<
path
.
count
()
-
1
;
i
++
)
{
sequenceNumber
=
_missionController
->
insertSimpleMissionItem
(
path
.
value
(
i
),
missionItems
->
count
());
_missionController
->
setCurrentPlanViewIndex
(
sequenceNumber
,
true
);
}
// create land position item
sequenceNumber
=
_missionController
->
insertSimpleMissionItem
(
_serArea
.
center
(),
missionItems
->
count
());
_missionController
->
setCurrentPlanViewIndex
(
sequenceNumber
,
true
);
SimpleMissionItem
*
landItem
=
qobject_cast
<
SimpleMissionItem
*>
(
missionItems
->
get
(
missionItems
->
count
()
-
1
));
if
(
landItem
==
nullptr
){
qWarning
(
"WimaPlaner::updateMission(): landItem == nullptr"
);
return
false
;
}
else
{
Vehicle
*
controllerVehicle
=
_masterController
->
controllerVehicle
();
MAV_CMD
landCmd
=
controllerVehicle
->
vtol
()
?
MAV_CMD_NAV_VTOL_LAND
:
MAV_CMD_NAV_LAND
;
if
(
controllerVehicle
->
firmwarePlugin
()
->
supportedMissionCommands
().
contains
(
landCmd
))
{
landItem
->
setCommand
(
landCmd
);
}
}
pushToContainer
();
setReadyForSaveSend
(
true
);
return
true
;
}
void
WimaPlaner
::
saveToCurrent
()
{
saveToFile
(
_currentFile
);
}
void
WimaPlaner
::
saveToFile
(
const
QString
&
filename
)
{
if
(
filename
.
isEmpty
())
{
return
;
}
QString
planFilename
=
filename
;
if
(
!
QFileInfo
(
filename
).
fileName
().
contains
(
"."
))
{
planFilename
+=
QString
(
".%1"
).
arg
(
wimaFileExtension
);
}
QFile
file
(
planFilename
);
if
(
!
file
.
open
(
QIODevice
::
WriteOnly
|
QIODevice
::
Text
))
{
qgcApp
()
->
showMessage
(
tr
(
"Plan save error %1 : %2"
).
arg
(
filename
).
arg
(
file
.
errorString
()));
_currentFile
.
clear
();
emit
currentFileChanged
();
}
else
{
FileType
fileType
=
FileType
::
WimaFile
;
if
(
planFilename
.
contains
(
QString
(
".%1"
).
arg
(
wimaFileExtension
))
)
{
fileType
=
FileType
::
WimaFile
;
}
else
if
(
planFilename
.
contains
(
QString
(
".%1"
).
arg
(
AppSettings
::
planFileExtension
))
)
{
fileType
=
FileType
::
PlanFile
;
}
else
{
if
(
planFilename
.
contains
(
"."
)
)
{
qgcApp
()
->
showMessage
(
tr
(
"File format not supported"
));
}
else
{
qgcApp
()
->
showMessage
(
tr
(
"File without file extension not accepted."
));
return
;
}
}
QJsonDocument
saveDoc
=
saveToJson
(
fileType
);
file
.
write
(
saveDoc
.
toJson
());
if
(
_currentFile
!=
planFilename
)
{
_currentFile
=
planFilename
;
emit
currentFileChanged
();
}
}
}
bool
WimaPlaner
::
loadFromCurrent
()
{
return
loadFromFile
(
_currentFile
);
}
bool
WimaPlaner
::
loadFromFile
(
const
QString
&
filename
)
{
#define debug 0
QString
errorString
;
QString
errorMessage
=
tr
(
"Error loading Plan file (%1). %2"
).
arg
(
filename
).
arg
(
"%1"
);
if
(
filename
.
isEmpty
())
{
return
false
;
}
QFileInfo
fileInfo
(
filename
);
QFile
file
(
filename
);
if
(
!
file
.
open
(
QIODevice
::
ReadOnly
|
QIODevice
::
Text
))
{
errorString
=
file
.
errorString
()
+
QStringLiteral
(
" "
)
+
filename
;
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
if
(
fileInfo
.
suffix
()
==
wimaFileExtension
)
{
QJsonDocument
jsonDoc
;
QByteArray
bytes
=
file
.
readAll
();
if
(
!
JsonHelper
::
isJsonFile
(
bytes
,
jsonDoc
,
errorString
))
{
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
QJsonObject
json
=
jsonDoc
.
object
();
// AreaItems
QJsonArray
areaArray
=
json
[
areaItemsName
].
toArray
();
_visualItems
.
clear
();
int
validAreaCounter
=
0
;
for
(
int
i
=
0
;
i
<
areaArray
.
size
()
&&
validAreaCounter
<
3
;
i
++
)
{
QJsonObject
jsonArea
=
areaArray
[
i
].
toObject
();
if
(
jsonArea
.
contains
(
WimaArea
::
areaTypeName
)
&&
jsonArea
[
WimaArea
::
areaTypeName
].
isString
())
{
if
(
jsonArea
[
WimaArea
::
areaTypeName
]
==
WimaGOperationArea
::
wimaGOperationAreaName
)
{
print
(
_opArea
);
bool
success
=
_opArea
.
loadFromJson
(
jsonArea
,
errorString
);
print
(
_opArea
);
if
(
!
success
)
{
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
validAreaCounter
++
;
_visualItems
.
append
(
&
_opArea
);
emit
visualItemsChanged
();
}
else
if
(
jsonArea
[
WimaArea
::
areaTypeName
]
==
WimaServiceArea
::
wimaServiceAreaName
)
{
bool
success
=
_serArea
.
loadFromJson
(
jsonArea
,
errorString
);
if
(
!
success
)
{
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
validAreaCounter
++
;
_visualItems
.
append
(
&
_serArea
);
emit
visualItemsChanged
();
}
else
if
(
jsonArea
[
WimaArea
::
areaTypeName
]
==
WimaVCorridor
::
wimaVCorridorName
)
{
bool
success
=
_corridor
.
loadFromJson
(
jsonArea
,
errorString
);
if
(
!
success
)
{
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
validAreaCounter
++
;
_visualItems
.
append
(
&
_corridor
);
emit
visualItemsChanged
();
}
else
{
errorString
+=
QString
(
tr
(
"%s not supported.
\n
"
).
arg
(
WimaArea
::
areaTypeName
));
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
}
else
{
errorString
+=
QString
(
tr
(
"Invalid or non existing entry for %s.
\n
"
).
arg
(
WimaArea
::
areaTypeName
));
return
false
;
}
}
_currentFile
.
sprintf
(
"%s/%s.%s"
,
fileInfo
.
path
().
toLocal8Bit
().
data
(),
fileInfo
.
completeBaseName
().
toLocal8Bit
().
data
(),
wimaFileExtension
);
emit
currentFileChanged
();
recalcJoinedArea
();
// MissionItems
// extrac MissionItems part
QJsonDocument
missionJsonDoc
=
QJsonDocument
(
json
[
missionItemsName
].
toObject
());
// create temporary file with missionItems
QFile
temporaryFile
;
QString
cropedFileName
=
filename
.
section
(
"/"
,
0
,
-
2
);
#if debug
qWarning
()
<<
cropedFileName
;
#endif
QString
temporaryFileName
;
for
(
int
i
=
0
;
;
i
++
)
{
temporaryFileName
=
cropedFileName
.
append
(
"/temp%1.%2"
).
arg
(
i
).
arg
(
AppSettings
::
planFileExtension
);
if
(
!
QFile
::
exists
(
temporaryFileName
)
)
{
temporaryFile
.
setFileName
(
temporaryFileName
);
if
(
temporaryFile
.
open
(
QIODevice
::
WriteOnly
|
QIODevice
::
Text
)
)
{
break
;
}
}
if
(
i
>
1000
)
{
qWarning
(
"WimaPlaner::loadFromFile(): not able to create temporary file."
);
return
false
;
}
}
temporaryFile
.
write
(
missionJsonDoc
.
toJson
());
// load from temporary file
_masterController
->
loadFromFile
(
temporaryFileName
);
// remove temporary file
if
(
!
temporaryFile
.
remove
()
){
qWarning
(
"WimaPlaner::loadFromFile(): not able to remove temporary file."
);
}
return
true
;
}
else
if
(
fileInfo
.
suffix
()
==
AppSettings
::
planFileExtension
){
_masterController
->
loadFromFile
(
filename
);
return
true
;
// might be wrong return value
}
else
{
errorString
+=
QString
(
tr
(
"File extension not supported.
\n
"
));
qgcApp
()
->
showMessage
(
errorMessage
.
arg
(
errorString
));
return
false
;
}
}
void
WimaPlaner
::
recalcPolygonInteractivity
(
int
index
)
{
if
(
index
>=
0
&&
index
<
_visualItems
.
count
())
{
resetAllInteractive
();
WimaArea
*
interactivePoly
=
qobject_cast
<
WimaArea
*>
(
_visualItems
.
get
(
index
));
interactivePoly
->
setInteractive
(
true
);
}
}
bool
WimaPlaner
::
recalcJoinedArea
()
{
// join service area, op area and corridor
_joinedArea
=
_serArea
;
_joinedArea
.
join
(
_corridor
);
if
(
!
_joinedArea
.
join
(
_opArea
)
)
return
false
;
// this happens if all areas are pairwise disjoint
else
{
emit
joinedAreaChanged
()
;
return
true
;
}
}
void
WimaPlaner
::
pushToContainer
()
{
// Sets the pointers (inside _container) to the areas (of this).
// Should be called only (once) after a _container has been assigned.
if
(
_container
!=
nullptr
)
{
_container
->
setOpArea
(
&
_opArea
);
_container
->
setSerArea
(
&
_serArea
);
_container
->
setCorridor
(
&
_corridor
);
_container
->
setJoinedArea
(
&
_joinedArea
);
_container
->
setVisualItems
(
&
_visualItems
);
}
else
{
qWarning
(
"WimaPlaner::uploadToContainer(): no container assigned."
);
}
}
void
WimaPlaner
::
resetAllInteractive
()
{
// Marks all areas as inactive (area.interactive == false)
int
itemCount
=
_visualItems
.
count
();
if
(
itemCount
>
0
){
for
(
int
i
=
0
;
i
<
itemCount
;
i
++
)
{
WimaArea
*
iteratorPoly
=
qobject_cast
<
WimaArea
*>
(
_visualItems
.
get
(
i
));
iteratorPoly
->
setInteractive
(
false
);
}
}
}
void
WimaPlaner
::
setInteractive
()
{
recalcPolygonInteractivity
(
_currentAreaIndex
);
}
QJsonDocument
WimaPlaner
::
saveToJson
(
FileType
fileType
)
{
/// This function save all areas (of WimaPlaner) and all mission items (of MissionController) to a QJsonDocument
/// @param fileType is either WimaFile or PlanFile (enum), if fileType == PlanFile only mission items are stored
QJsonObject
json
;
if
(
fileType
==
FileType
::
WimaFile
)
{
QJsonArray
jsonArray
;
for
(
int
i
=
0
;
i
<
_visualItems
.
count
();
i
++
)
{
QJsonObject
json
;
WimaArea
*
area
=
qobject_cast
<
WimaArea
*>
(
_visualItems
.
get
(
i
));
if
(
area
==
nullptr
)
{
qWarning
(
"WimaPlaner::saveToJson(): Internal error, area == nullptr!"
);
return
QJsonDocument
();
}
// check the type of area, create and append the JsonObject to the JsonArray once determined
WimaGOperationArea
*
opArea
=
qobject_cast
<
WimaGOperationArea
*>
(
area
);
if
(
opArea
!=
nullptr
)
{
opArea
->
saveToJson
(
json
);
jsonArray
.
append
(
json
);
continue
;
}
WimaServiceArea
*
serArea
=
qobject_cast
<
WimaServiceArea
*>
(
area
);
if
(
serArea
!=
nullptr
)
{
serArea
->
saveToJson
(
json
);
jsonArray
.
append
(
json
);
continue
;
}
WimaVCorridor
*
corridor
=
qobject_cast
<
WimaVCorridor
*>
(
area
);
if
(
corridor
!=
nullptr
)
{
corridor
->
saveToJson
(
json
);
jsonArray
.
append
(
json
);
continue
;
}
// if non of the obove branches was trigger, type must be WimaArea
area
->
saveToJson
(
json
);
jsonArray
.
append
(
json
);
}
json
[
areaItemsName
]
=
jsonArray
;
json
[
missionItemsName
]
=
_masterController
->
saveToJson
().
object
();
return
QJsonDocument
(
json
);
}
else
if
(
fileType
==
FileType
::
PlanFile
)
{
return
_masterController
->
saveToJson
();
}
return
QJsonDocument
(
json
);
}
void
WimaPlaner
::
setReadyForSaveSend
(
bool
ready
)
{
if
(
ready
!=
_readyForSaveSend
)
{
_readyForSaveSend
=
ready
;
emit
readyForSaveSendChanged
(
ready
);
}
}
src/Wima/WimaPlaner.h
View file @
b37dda84
#ifndef WIMAPLANER_H
#define WIMAPLANER_H
#pragma once
#include <QObject>
#include "QGCMapPolygon.h"
#include "QmlObjectListModel.h"
class
WimaPlaner
#include "WimaArea.h"
#include "WimaGOperationArea.h"
#include "WimaServiceArea.h"
#include "WimaVCorridor.h"
#include "WimaDataContainer.h"
#include "PlanMasterController.h"
#include "MissionController.h"
#include "SurveyComplexItem.h"
#include "SimpleMissionItem.h"
#include "MissionSettingsItem.h"
#include "JsonHelper.h"
#include "QGCApplication.h"
class
WimaPlaner
:
public
QObject
{
Q_OBJECT
enum
FileType
{
WimaFile
,
PlanFile
};
public:
WimaPlaner
();
};
WimaPlaner
(
QObject
*
parent
=
nullptr
);
template
<
class
T
>
WimaPlaner
(
T
t
,
QObject
*
parent
=
nullptr
)
=
delete
;
template
<
class
T
>
WimaPlaner
(
T
t
)
=
delete
;
Q_PROPERTY
(
PlanMasterController
*
masterController
READ
masterController
WRITE
setMasterController
NOTIFY
masterControllerChanged
)
Q_PROPERTY
(
MissionController
*
missionController
READ
missionController
WRITE
setMissionController
NOTIFY
missionControllerChanged
)
Q_PROPERTY
(
QmlObjectListModel
*
visualItems
READ
visualItems
NOTIFY
visualItemsChanged
)
Q_PROPERTY
(
int
currentPolygonIndex
READ
currentPolygonIndex
WRITE
setCurrentPolygonIndex
NOTIFY
currentPolygonIndexChanged
)
Q_PROPERTY
(
QString
currentFile
READ
currentFile
NOTIFY
currentFileChanged
)
Q_PROPERTY
(
QStringList
loadNameFilters
READ
loadNameFilters
CONSTANT
)
Q_PROPERTY
(
QStringList
saveNameFilters
READ
saveNameFilters
CONSTANT
)
Q_PROPERTY
(
QString
fileExtension
READ
fileExtension
CONSTANT
)
Q_PROPERTY
(
QGeoCoordinate
joinedAreaCenter
READ
joinedAreaCenter
CONSTANT
)
Q_PROPERTY
(
WimaArea
joinedArea
READ
joinedArea
NOTIFY
joinedAreaChanged
)
Q_PROPERTY
(
WimaDataContainer
*
dataContainer
WRITE
setDataContainer
NOTIFY
dataContainerChanged
)
Q_PROPERTY
(
bool
readyForSaveSend
READ
readyForSaveSend
NOTIFY
readyForSaveSendChanged
)
// Property accessors
PlanMasterController
*
masterController
(
void
)
const
{
return
_masterController
;
}
MissionController
*
missionController
(
void
)
const
{
return
_missionController
;
}
QmlObjectListModel
*
visualItems
(
void
)
;
int
currentPolygonIndex
(
void
)
const
{
return
_currentAreaIndex
;
}
QString
currentFile
(
void
)
const
{
return
_currentFile
;
}
QStringList
loadNameFilters
(
void
)
const
;
QStringList
saveNameFilters
(
void
)
const
;
QString
fileExtension
(
void
)
const
{
return
wimaFileExtension
;
}
QGeoCoordinate
joinedAreaCenter
(
void
)
const
;
WimaArea
joinedArea
(
void
)
const
;
bool
readyForSaveSend
(
void
)
const
{
return
_readyForSaveSend
;
}
#endif // WIMAPLANER_H
\ No newline at end of file
// Property setters
void
setMasterController
(
PlanMasterController
*
masterController
);
void
setMissionController
(
MissionController
*
missionController
);
/// Sets the integer index pointing to the current polygon. Current polygon is set interactive.
void
setCurrentPolygonIndex
(
int
index
);
void
setDataContainer
(
WimaDataContainer
*
container
);
// Member Methodes
Q_INVOKABLE
void
startWimaPlaner
(
bool
flyView
);
Q_INVOKABLE
bool
addGOperationArea
();
/// Removes an area from _visualItems
/// @param index Index of the area to be removed
Q_INVOKABLE
void
removeArea
(
int
index
);
Q_INVOKABLE
bool
addServiceArea
();
Q_INVOKABLE
bool
addVehicleCorridor
();
/// Remove all areas from WimaPlaner and all mission items from MissionController
Q_INVOKABLE
void
removeAll
();
Q_INVOKABLE
void
startMission
();
Q_INVOKABLE
void
abortMission
();
Q_INVOKABLE
void
pauseMission
();
Q_INVOKABLE
void
resumeMission
();
/// Recalculates vehicle corridor, flight path, etc.
Q_INVOKABLE
bool
updateMission
();
Q_INVOKABLE
void
saveToCurrent
();
Q_INVOKABLE
void
saveToFile
(
const
QString
&
filename
);
Q_INVOKABLE
bool
loadFromCurrent
();
Q_INVOKABLE
bool
loadFromFile
(
const
QString
&
filename
);
Q_INVOKABLE
void
resetAllInteractive
(
void
);
Q_INVOKABLE
void
setInteractive
(
void
);
// static Members
static
const
char
*
wimaFileExtension
;
static
const
char
*
areaItemsName
;
static
const
char
*
missionItemsName
;
// Member Methodes
QJsonDocument
saveToJson
(
FileType
fileType
);
void
setReadyForSaveSend
(
bool
ready
);
signals:
void
masterControllerChanged
(
void
);
void
missionControllerChanged
(
void
);
void
visualItemsChanged
(
void
);
void
currentPolygonIndexChanged
(
int
index
);
void
currentFileChanged
();
void
joinedAreaChanged
();
void
dataContainerChanged
();
void
readyForSaveSendChanged
(
bool
ready
);
private
slots
:
void
recalcPolygonInteractivity
(
int
index
);
bool
recalcJoinedArea
();
void
pushToContainer
();
private:
bool
_readyForSaveSend
;
// basically true if updateMission() was sucessful
PlanMasterController
*
_masterController
;
MissionController
*
_missionController
;
int
_currentAreaIndex
;
QString
_currentFile
;
// file for saveing
WimaDataContainer
*
_container
;
// container for data exchange with WimaController
QmlObjectListModel
_visualItems
;
// contains all visible areas
WimaArea
_joinedArea
;
// joined area fromed by opArea, serArea, _corridor
WimaGOperationArea
_opArea
;
// measurement area
WimaServiceArea
_serArea
;
// area for supplying
WimaVCorridor
_corridor
;
// corridor connecting opArea and serArea
};
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