Commit f9d811fa authored by Gus Grubba's avatar Gus Grubba

Merge branch 'master' of https://github.com/mavlink/qgroundcontrol into pr-mgrs

parents 3be7c93b 67204922
......@@ -6,6 +6,7 @@ Note: This file only contains high level features or important fixes.
### 3.6.0 - Daily Build
* ADSB: Added support for connecting to SBS server. Adds support for ADSB data from USB SDR Dongle running 'dump1090 --net' for example.
* Toolbar: Scrollable left/right on small screens like phones
* Plan View: New create plan UI for initial plan creation
* New Corridor editing tools ui. Includes ability to trace polyline by clicking.
......
This system is for posting bugs or feature requests ONLY. For questions about how to use or build QGC see: http://qgroundcontrol.com/#resources
# This system is for posting bugs or feature requests ONLY. Support questions will be automatically closed with no response.
# For questions about how to use or build QGC see: http://qgroundcontrol.com/#resources
----
# To post a bug report
When posting bug reports, include the following informaiton:
- Ground station operating system.
- QGroundControl version and build (daily, stable, self-built from source, etc.)
......
......@@ -5,15 +5,18 @@ pipeline {
stage('build') {
parallel {
stage('Android Release') {
stage('Android 32 bit Release') {
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
CCACHE_CPP2 = '1'
QGC_CONFIG = 'release'
QMAKE_VER = "5.11.0/android_armv7/bin/qmake"
QMAKE_VER = "5.12.5/android_armv7/bin/qmake"
QT_MKSPEC = "android-clang"
BITNESS=32
}
agent {
docker {
image 'mavlink/qgc-build-android:2019-02-03'
image 'mavlink/qgc-build-android:2019-11-12'
args '-v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
......@@ -34,15 +37,47 @@ pipeline {
}
}
stage('Android 64 bit Release') {
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
CCACHE_CPP2 = '1'
QGC_CONFIG = 'release'
QMAKE_VER = "5.12.5/android_arm64_v8a/bin/qmake"
QT_MKSPEC = "android-clang"
BITNESS=64
}
agent {
docker {
image 'mavlink/qgc-build-android_arm64_v8a:2019-11-12'
args '-v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
steps {
sh 'export'
sh 'ccache -z'
sh 'git submodule deinit -f .'
sh 'git clean -ff -x -d .'
sh 'git submodule update --init --recursive --force'
sh 'mkdir build; cd build; ${QT_PATH}/${QMAKE_VER} -r ${WORKSPACE}/qgroundcontrol.pro CONFIG+=${QGC_CONFIG} CONFIG+=WarningsAsErrorsOn'
//sh 'cd build; make -j`nproc --all`' // FIXME
sh 'ccache -s'
}
post {
cleanup {
sh 'git clean -ff -x -d .'
}
}
}
stage('Linux Debug') {
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
QGC_CONFIG = 'debug'
QMAKE_VER = "5.11.0/gcc_64/bin/qmake"
QMAKE_VER = "5.12.5/gcc_64/bin/qmake"
}
agent {
docker {
image 'mavlink/qgc-build-linux:2019-02-03'
image 'mavlink/qgc-build-linux:2019-11-12'
args '-v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
......@@ -67,12 +102,12 @@ pipeline {
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
CMAKE_BUILD_TYPE = 'Debug'
QT_VERSION = "5.11.0"
QT_VERSION = "5.12.5"
QT_MKSPEC = "gcc_64"
}
agent {
docker {
image 'mavlink/qgc-build-linux:2019-02-03'
image 'mavlink/qgc-build-linux:2019-11-12'
args '-v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
......@@ -97,11 +132,11 @@ pipeline {
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
QGC_CONFIG = 'release'
QMAKE_VER = "5.11.0/gcc_64/bin/qmake"
QMAKE_VER = "5.12.5/gcc_64/bin/qmake"
}
agent {
docker {
image 'mavlink/qgc-build-linux:2019-02-03'
image 'mavlink/qgc-build-linux:2019-11-12'
args '-v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
......@@ -129,12 +164,12 @@ pipeline {
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
CMAKE_BUILD_TYPE = 'Release'
QT_VERSION = "5.11.0"
QT_VERSION = "5.12.5"
QT_MKSPEC = "gcc_64"
}
agent {
docker {
image 'mavlink/qgc-build-linux:2019-02-03'
image 'mavlink/qgc-build-linux:2019-11-12'
args '-v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
......@@ -190,6 +225,7 @@ pipeline {
}
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
CCACHE_CPP2 = '1'
CMAKE_BUILD_TYPE = 'Debug'
QT_VERSION = "5.11.0"
QT_MKSPEC = "clang_64"
......@@ -218,6 +254,7 @@ pipeline {
}
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
CCACHE_CPP2 = '1'
QGC_CONFIG = 'installer'
QMAKE_VER = "5.11.0/clang_64/bin/qmake"
}
......@@ -270,6 +307,7 @@ pipeline {
}
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
CCACHE_CPP2 = '1'
CMAKE_BUILD_TYPE = 'Release'
QT_VERSION = "5.11.0"
QT_MKSPEC = "clang_64"
......@@ -295,7 +333,6 @@ pipeline {
} // stages
environment {
CCACHE_CPP2 = '1'
CCACHE_DIR = '/tmp/ccache'
QT_FATAL_WARNINGS = '1'
}
......
---
name: Bug report
about: Create a report to help us improve
---
**Describe the bug**
A clear and concise description of the bug.
**To Reproduce**
Steps to reproduce the behavior:
1. Drone switched on '...'
2. Uploaded mission '....' (attach QGC mission file)
3. Took off '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Log Files and Screenshots**
*Always* add screenshots and the QGC console log.
**Drone (please complete the following information):**
- Describe the type of drone.
- Photo of the IMU / autopilot setup if possible.
**Additional context**
Add any other context about the problem here.
......@@ -4,7 +4,7 @@ endif()
if(NOT QT_VERSION)
# try Qt 5.12.0 if none specified, last LTS.
set(QT_VERSION "5.12.0")
set(QT_VERSION "5.12.5")
endif()
if(DEFINED ENV{QT_MKSPEC})
......
......@@ -39,6 +39,8 @@ add_compile_options(
-Wno-return-type
)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Use rpath?
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# No rpath on Darwin. Setting it will only cause trouble.
......@@ -175,7 +177,7 @@ if(BUILD_TEST)
endif(BUILD_TEST)
foreach(executable ${executables})
add_executable(${executable} ${executable}.c)
add_executable(${executable} EXCLUDE_FROM_ALL ${executable}.c)
target_link_libraries(${executable} shp)
if(USE_RPATH)
set_target_properties(${executable}
......@@ -200,7 +202,7 @@ if(BUILD_TEST)
# Other executables to be built to facilitate tests.
foreach(executable shptest shputils)
add_executable(${executable} ${executable}.c)
add_executable(${executable} EXCLUDE_FROM_ALL ${executable}.c)
target_link_libraries(${executable} shp)
get_target_property(${executable}_LOC ${executable} LOCATION)
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/script.sed "s?\\./${executable}?${${executable}_LOC}?\n")
......
......@@ -127,7 +127,7 @@
<file alias="pipHide.svg">src/FlightMap/Images/pipHide.svg</file>
<file alias="pipResize.svg">src/FlightMap/Images/pipResize.svg</file>
<file alias="Plan.svg">src/ui/toolbar/Images/Plan.svg</file>
<file alias="PlanCreator/CustomPlanCreator.png">src/MissionManager/CustomPlanCreator.png</file>
<file alias="PlanCreator/BlankPlanCreator.png">src/MissionManager/BlankPlanCreator.png</file>
<file alias="PlanCreator/CorridorScanPlanCreator.png">src/MissionManager/CorridorScanPlanCreator.png</file>
<file alias="PlanCreator/StructureScanPlanCreator.png">src/MissionManager/StructureScanPlanCreator.png</file>
<file alias="PlanCreator/SurveyPlanCreator.png">src/MissionManager/SurveyPlanCreator.png</file>
......
......@@ -398,6 +398,7 @@ INCLUDEPATH += .
INCLUDEPATH += \
include/ui \
src \
src/ADSB \
src/api \
src/AnalyzeView \
src/Camera \
......@@ -567,6 +568,8 @@ DebugBuild { PX4FirmwarePlugin { PX4FirmwarePluginFactory { APMFirmwarePlugin {
# Main QGC Headers and Source files
HEADERS += \
src/ADSB/ADSBVehicle.h \
src/ADSB/ADSBVehicleManager.h \
src/AnalyzeView/LogDownloadController.h \
src/AnalyzeView/PX4LogParser.h \
src/AnalyzeView/ULogParser.h \
......@@ -593,7 +596,7 @@ HEADERS += \
src/MissionManager/ComplexMissionItem.h \
src/MissionManager/CorridorScanComplexItem.h \
src/MissionManager/CorridorScanPlanCreator.h \
src/MissionManager/CustomPlanCreator.h \
src/MissionManager/BlankPlanCreator.h \
src/MissionManager/FixedWingLandingComplexItem.h \
src/MissionManager/GeoFenceController.h \
src/MissionManager/GeoFenceManager.h \
......@@ -624,6 +627,7 @@ HEADERS += \
src/MissionManager/StructureScanPlanCreator.h \
src/MissionManager/SurveyComplexItem.h \
src/MissionManager/SurveyPlanCreator.h \
src/MissionManager/TakeoffMissionItem.h \
src/MissionManager/TransectStyleComplexItem.h \
src/MissionManager/VisualMissionItem.h \
src/PositionManager/PositionManager.h \
......@@ -659,6 +663,7 @@ HEADERS += \
src/QmlControls/RCChannelMonitorController.h \
src/QmlControls/ScreenToolsController.h \
src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h \
src/Settings/ADSBVehicleManagerSettings.h \
src/Settings/AppSettings.h \
src/Settings/AutoConnectSettings.h \
src/Settings/BrandImageSettings.h \
......@@ -676,7 +681,6 @@ HEADERS += \
src/SHPFileHelper.h \
src/Terrain/TerrainQuery.h \
src/TerrainTile.h \
src/Vehicle/ADSBVehicle.h \
src/Vehicle/GPSRTKFactGroup.h \
src/Vehicle/MAVLinkLogManager.h \
src/Vehicle/MultiVehicleManager.h \
......@@ -806,6 +810,8 @@ AndroidBuild {
}
SOURCES += \
src/ADSB/ADSBVehicle.cc \
src/ADSB/ADSBVehicleManager.cc \
src/AnalyzeView/LogDownloadController.cc \
src/AnalyzeView/PX4LogParser.cc \
src/AnalyzeView/ULogParser.cc \
......@@ -830,7 +836,7 @@ SOURCES += \
src/MissionManager/ComplexMissionItem.cc \
src/MissionManager/CorridorScanComplexItem.cc \
src/MissionManager/CorridorScanPlanCreator.cc \
src/MissionManager/CustomPlanCreator.cc \
src/MissionManager/BlankPlanCreator.cc \
src/MissionManager/FixedWingLandingComplexItem.cc \
src/MissionManager/GeoFenceController.cc \
src/MissionManager/GeoFenceManager.cc \
......@@ -860,6 +866,7 @@ SOURCES += \
src/MissionManager/StructureScanPlanCreator.cc \
src/MissionManager/SurveyComplexItem.cc \
src/MissionManager/SurveyPlanCreator.cc \
src/MissionManager/TakeoffMissionItem.cc \
src/MissionManager/TransectStyleComplexItem.cc \
src/MissionManager/VisualMissionItem.cc \
src/PositionManager/PositionManager.cpp \
......@@ -893,6 +900,7 @@ SOURCES += \
src/QmlControls/RCChannelMonitorController.cc \
src/QmlControls/ScreenToolsController.cc \
src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc \
src/Settings/ADSBVehicleManagerSettings.cc \
src/Settings/AppSettings.cc \
src/Settings/AutoConnectSettings.cc \
src/Settings/BrandImageSettings.cc \
......@@ -910,7 +918,6 @@ SOURCES += \
src/SHPFileHelper.cc \
src/Terrain/TerrainQuery.cc \
src/TerrainTile.cc\
src/Vehicle/ADSBVehicle.cc \
src/Vehicle/GPSRTKFactGroup.cc \
src/Vehicle/MAVLinkLogManager.cc \
src/Vehicle/MultiVehicleManager.cc \
......
......@@ -102,7 +102,6 @@
<file alias="QGroundControl/Controls/ParameterEditorDialog.qml">src/QmlControls/ParameterEditorDialog.qml</file>
<file alias="QGroundControl/Controls/PIDTuning.qml">src/QmlControls/PIDTuning.qml</file>
<file alias="QGroundControl/Controls/PlanEditToolbar.qml">src/PlanView/PlanEditToolbar.qml</file>
<file alias="QGroundControl/Controls/PlanStartOverlay.qml">src/PlanView/PlanStartOverlay.qml</file>
<file alias="QGroundControl/Controls/PreFlightCheckButton.qml">src/QmlControls/PreFlightCheckButton.qml</file>
<file alias="QGroundControl/Controls/PreFlightCheckGroup.qml">src/QmlControls/PreFlightCheckGroup.qml</file>
<file alias="QGroundControl/Controls/PreFlightCheckModel.qml">src/QmlControls/PreFlightCheckModel.qml</file>
......@@ -153,6 +152,7 @@
<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/TakeoffItemMapVisual.qml">src/PlanView/TakeoffItemMapVisual.qml</file>
<file alias="QGroundControl/Controls/ToolStrip.qml">src/QmlControls/ToolStrip.qml</file>
<file alias="QGroundControl/Controls/TransectStyleComplexItemStats.qml">src/PlanView/TransectStyleComplexItemStats.qml</file>
<file alias="QGroundControl/Controls/TransectStyleMapVisuals.qml">src/PlanView/TransectStyleMapVisuals.qml</file>
......@@ -234,6 +234,7 @@
<qresource prefix="/json">
<file alias="APMMavlinkStreamRate.SettingsGroup.json">src/Settings/APMMavlinkStreamRate.SettingsGroup.json</file>
<file alias="BreachReturn.FactMetaData.json">src/MissionManager/BreachReturn.FactMetaData.json</file>
<file alias="ADSBVehicleManager.SettingsGroup.json">src/Settings/ADSBVehicleManager.SettingsGroup.json</file>
<file alias="App.SettingsGroup.json">src/Settings/App.SettingsGroup.json</file>
<file alias="AutoConnect.SettingsGroup.json">src/Settings/AutoConnect.SettingsGroup.json</file>
<file alias="BrandImage.SettingsGroup.json">src/Settings/BrandImage.SettingsGroup.json</file>
......
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="-89 46 72 72" enable-background="new -89 46 72 72" xml:space="preserve">
<rect x="-78.911" y="46" fill="#FFFFFF" width="51.822" height="10.66"/>
<path fill="#FFFFFF" d="M-27.089,59.781h-51.822V118h51.822L-27.089,59.781L-27.089,59.781z M-33.927,110.332h-7.17V68.068h7.17
V110.332z M-49.416,110.332h-7.17V68.068h7.17V110.332z M-64.245,110.332h-7.17V68.068h7.17V110.332z"/>
</svg>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
viewBox="-89 46 72 72"
enable-background="new -89 46 72 72"
xml:space="preserve"
sodipodi:docname="TrashDelete.svg"
inkscape:version="0.92.4 (f8dce91, 2019-08-02)"><metadata
id="metadata3771"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs3769"><inkscape:path-effect
effect="bspline"
id="path-effect3883"
is_visible="true"
weight="50"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" /><inkscape:path-effect
effect="bspline"
id="path-effect3874"
is_visible="true"
weight="10"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" /><filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter3830"
x="-1.2740651"
width="3.5481301"
y="-1.1340731"
height="3.2681461"><feBlend
inkscape:collect="always"
mode="lighten"
in2="BackgroundImage"
id="feBlend3834" /></filter><inkscape:path-effect
effect="bspline"
id="path-effect3883-3"
is_visible="true"
weight="50"
steps="2"
helper_size="0"
apply_no_weight="true"
apply_with_weight="true"
only_selected="false" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1735"
inkscape:window-height="1038"
id="namedview3767"
showgrid="false"
inkscape:pagecheckerboard="true"
inkscape:zoom="2.9861111"
inkscape:cx="-39.595586"
inkscape:cy="61.570647"
inkscape:window-x="2103"
inkscape:window-y="20"
inkscape:window-maximized="0"
inkscape:current-layer="Layer_1" />
<path
style="fill:#ffffff;stroke-width:1.1104244"
d="m -81.92009,46.487004 c 0.487005,-0.487004 57.353171,-0.487004 57.840175,0 0.487005,0.487005 2.055265,2.055266 2.54227,2.54227 0.487005,0.487005 0.487005,4.114447 0,4.601451 -0.487004,0.487005 -2.055265,2.055266 -2.54227,2.54227 -0.487004,0.487005 -57.35317,0.487005 -57.840175,0 -0.487004,-0.487004 -2.055265,-2.055265 -2.54227,-2.54227 -0.487004,-0.487004 -0.487004,-4.114446 10e-7,-4.601451 0.487005,-0.487005 2.055265,-2.055265 2.542269,-2.54227 z"
id="rect3762"
inkscape:path-effect="#path-effect3883"
inkscape:original-d="m -81.433085,46 h 56.866166 c 1.948018,0 3.516279,1.56826 3.516279,3.516279 v 3.627442 c 0,1.948018 -1.568261,3.516279 -3.516279,3.516279 h -56.866166 c -1.948018,0 -3.516279,-1.568261 -3.516279,-3.516279 V 49.516279 C -84.949364,47.56826 -83.381103,46 -81.433085,46 Z"
inkscape:connector-curvature="0"
transform="matrix(0.83070712,0,0,0.82950228,-8.6376373,16.905515)" />
<g
inkscape:groupmode="layer"
id="layer1"
inkscape:label="Layer 1"
style="display:inline" /><path
d="m -29.6796,62.69245 c -2.5906,-2.91145 -44.0482,-2.91145 -46.6398,0 -2.5916,2.91145 -2.5916,49.48665 0,52.3971 2.5916,2.91045 44.0492,2.91045 46.6398,0 2.5906,-2.91045 2.5906,-49.48565 0,-52.3971 z m -4.6054,45.52685 c -0.358,2.1127 -6.094,2.1127 -6.453,0 -0.359,-2.1127 -0.359,-35.9239 0,-38.0376 0.359,-2.1137 6.095,-2.1137 6.453,0 0.358,2.1137 0.358,35.9249 0,38.0376 z m -15.489,0 c -0.358,2.1127 -6.094,2.1127 -6.453,0 -0.359,-2.1127 -0.359,-35.9239 0,-38.0376 0.359,-2.1137 6.095,-2.1137 6.453,0 0.358,2.1137 0.358,35.9249 0,38.0376 z m -14.829,0 c -0.358,2.1127 -6.094,2.1127 -6.453,0 -0.359,-2.1127 -0.359,-35.9239 0,-38.0376 0.359,-2.1137 6.095,-2.1137 6.453,0 0.358,2.1137 0.358,35.9249 0,38.0376 z"
id="path3764"
inkscape:connector-curvature="0"
style="fill:#ffffff;filter:url(#filter3830)"
inkscape:path-effect="#path-effect3874"
inkscape:original-d="m -27.089,59.781 c -5.1812,10e-4 -46.6388,10e-4 -51.822,0 0.001,5.8229 0.001,52.3981 0,58.219 5.1832,0.001 46.6408,0.001 51.822,0 10e-4,-5.8209 10e-4,-52.3961 0,-58.219 z m -6.838,50.551 c -0.716,0.001 -6.452,0.001 -7.17,0 0.001,-4.2254 0.001,-38.0366 0,-42.264 0.718,0.001 6.454,0.001 7.17,0 10e-4,4.2274 10e-4,38.0386 0,42.264 z m -15.489,0 c -0.716,0.001 -6.452,0.001 -7.17,0 10e-4,-4.2254 10e-4,-38.0366 0,-42.264 0.718,0.001 6.454,0.001 7.17,0 10e-4,4.2274 10e-4,38.0386 0,42.264 z m -14.829,0 c -0.716,0.001 -6.452,0.001 -7.17,0 0.001,-4.2254 0.001,-38.0366 0,-42.264 0.718,0.001 6.454,0.001 7.17,0 0.001,4.2274 0.001,38.0386 0,42.264 z"
transform="matrix(1,0,0,0.76115058,0.66964846,21.432082)" /><g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="Layer 3" /><g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2" /><path
style="fill:#ffffff;stroke-width:1.1104244"
d="m -81.92009,46.487004 c 0.487005,-0.487004 57.353171,-0.487004 57.840175,0 0.487005,0.487005 2.055265,2.055266 2.54227,2.54227 0.487005,0.487005 0.487005,4.114447 0,4.601451 -0.487004,0.487005 -2.055265,2.055266 -2.54227,2.54227 -0.487004,0.487005 -57.35317,0.487005 -57.840175,0 -0.487004,-0.487004 -2.055265,-2.055265 -2.54227,-2.54227 -0.487004,-0.487004 -0.487004,-4.114446 10e-7,-4.601451 0.487005,-0.487005 2.055265,-2.055265 2.542269,-2.54227 z"
id="rect3762-6"
inkscape:path-effect="#path-effect3883-3"
inkscape:original-d="m -81.433085,46 h 56.866166 c 1.948018,0 3.516279,1.56826 3.516279,3.516279 v 3.627442 c 0,1.948018 -1.568261,3.516279 -3.516279,3.516279 h -56.866166 c -1.948018,0 -3.516279,-1.568261 -3.516279,-3.516279 V 49.516279 C -84.949364,47.56826 -83.381103,46 -81.433085,46 Z"
inkscape:connector-curvature="0"
transform="matrix(0.20525298,0,0,0.52828964,-41.786708,26.697818)" /></svg>
\ No newline at end of file
/****************************************************************************
*
* (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 "ADSBVehicle.h"
#include "QGCLoggingCategory.h"
#include <QDebug>
#include <QtMath>
ADSBVehicle::ADSBVehicle(const VehicleInfo_t& vehicleInfo, QObject* parent)
: QObject (parent)
, _icaoAddress (vehicleInfo.icaoAddress)
, _altitude (qQNaN())
, _heading (qQNaN())
, _alert (false)
{
update(vehicleInfo);
}
void ADSBVehicle::update(const VehicleInfo_t& vehicleInfo)
{
if (_icaoAddress != vehicleInfo.icaoAddress) {
qCWarning(ADSBVehicleManagerLog) << "ICAO address mismatch expected:actual" << _icaoAddress << vehicleInfo.icaoAddress;
return;
}
if (vehicleInfo.availableFlags & CallsignAvailable) {
if (vehicleInfo.callsign != _callsign) {
_callsign = vehicleInfo.callsign;
emit callsignChanged();
}
}
if (vehicleInfo.availableFlags & LocationAvailable) {
if (_coordinate != vehicleInfo.location) {
_coordinate = vehicleInfo.location;
emit coordinateChanged();
}
}
if (vehicleInfo.availableFlags & AltitudeAvailable) {
if (!(qIsNaN(vehicleInfo.altitude) && qIsNaN(_altitude)) && !qFuzzyCompare(vehicleInfo.altitude, _altitude)) {
_altitude = vehicleInfo.altitude;
emit altitudeChanged();
}
}
if (vehicleInfo.availableFlags & HeadingAvailable) {
if (!(qIsNaN(vehicleInfo.heading) && qIsNaN(_heading)) && !qFuzzyCompare(vehicleInfo.heading, _heading)) {
_heading = vehicleInfo.heading;
emit headingChanged();
}
}
if (vehicleInfo.availableFlags & AlertAvailable) {
if (vehicleInfo.alert != _alert) {
_alert = vehicleInfo.alert;
emit alertChanged();
}
}
_lastUpdateTimer.restart();
}
bool ADSBVehicle::expired()
{
return _lastUpdateTimer.hasExpired(expirationTimeoutMs);
}
......@@ -20,9 +20,25 @@ class ADSBVehicle : public QObject
Q_OBJECT
public:
ADSBVehicle(mavlink_adsb_vehicle_t& adsbVehicle, QObject* parent = nullptr);
enum {
CallsignAvailable = 1 << 1,
LocationAvailable = 1 << 2,
AltitudeAvailable = 1 << 3,
HeadingAvailable = 1 << 4,
AlertAvailable = 1 << 5,
};
ADSBVehicle(const QGeoCoordinate& location, float heading, bool alert = false, QObject* parent = nullptr);
typedef struct {
uint32_t icaoAddress; // Required
QString callsign;
QGeoCoordinate location;
double altitude;
double heading;
bool alert;
uint32_t availableFlags;
} VehicleInfo_t;
ADSBVehicle(const VehicleInfo_t& vehicleInfo, QObject* parent);
Q_PROPERTY(int icaoAddress READ icaoAddress CONSTANT)
Q_PROPERTY(QString callsign READ callsign NOTIFY callsignChanged)
......@@ -31,17 +47,14 @@ public:
Q_PROPERTY(double heading READ heading NOTIFY headingChanged) // NaN for not available
Q_PROPERTY(bool alert READ alert NOTIFY alertChanged) // Collision path
int icaoAddress (void) const { return _icaoAddress; }
int icaoAddress (void) const { return static_cast<int>(_icaoAddress); }
QString callsign (void) const { return _callsign; }
QGeoCoordinate coordinate (void) const { return _coordinate; }
double altitude (void) const { return _altitude; }
double heading (void) const { return _heading; }
bool alert (void) const { return _alert; }
/// Update the vehicle with new information
void update(mavlink_adsb_vehicle_t& adsbVehicle);
void update(bool alert, const QGeoCoordinate& location, float heading);
void update(const VehicleInfo_t& vehicleInfo);
/// check if the vehicle is expired and should be removed
bool expired();
......@@ -69,3 +82,6 @@ private:
QElapsedTimer _lastUpdateTimer;
};
Q_DECLARE_METATYPE(ADSBVehicle::VehicleInfo_t)
/****************************************************************************
*
* (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 "ADSBVehicleManager.h"
#include "QGCLoggingCategory.h"
#include "QGCApplication.h"
#include "SettingsManager.h"
#include "ADSBVehicleManagerSettings.h"
#include <QDebug>
ADSBVehicleManager::ADSBVehicleManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
{
}
void ADSBVehicleManager::setToolbox(QGCToolbox* toolbox)
{
QGCTool::setToolbox(toolbox);
connect(&_adsbVehicleCleanupTimer, &QTimer::timeout, this, &ADSBVehicleManager::_cleanupStaleVehicles);
_adsbVehicleCleanupTimer.setSingleShot(false);
_adsbVehicleCleanupTimer.start(1000);
ADSBVehicleManagerSettings* settings = qgcApp()->toolbox()->settingsManager()->adsbVehicleManagerSettings();
if (settings->adsbServerConnectEnabled()->rawValue().toBool()) {
_tcpLink = new ADSBTCPLink(settings->adsbServerHostAddress()->rawValue().toString(), settings->adsbServerPort()->rawValue().toInt(), this);
connect(_tcpLink, &ADSBTCPLink::adsbVehicleUpdate, this, &ADSBVehicleManager::adsbVehicleUpdate, Qt::QueuedConnection);
connect(_tcpLink, &ADSBTCPLink::error, this, &ADSBVehicleManager::_tcpError, Qt::QueuedConnection);
}
}
void ADSBVehicleManager::_cleanupStaleVehicles()
{
// Remove all expired ADSB vehicles
for (int i=_adsbVehicles.count()-1; i>=0; i--) {
ADSBVehicle* adsbVehicle = _adsbVehicles.value<ADSBVehicle*>(i);
if (adsbVehicle->expired()) {
qCDebug(ADSBVehicleManagerLog) << "Expired" << QStringLiteral("%1").arg(adsbVehicle->icaoAddress(), 0, 16);
_adsbVehicles.removeAt(i);
adsbVehicle->deleteLater();
}
}
}
void ADSBVehicleManager::adsbVehicleUpdate(const ADSBVehicle::VehicleInfo_t vehicleInfo)
{
uint32_t icaoAddress = vehicleInfo.icaoAddress;
if (_adsbICAOMap.contains(icaoAddress)) {
_adsbICAOMap[icaoAddress]->update(vehicleInfo);
} else {
if (vehicleInfo.availableFlags & ADSBVehicle::LocationAvailable) {
ADSBVehicle* adsbVehicle = new ADSBVehicle(vehicleInfo, this);
_adsbICAOMap[icaoAddress] = adsbVehicle;
_adsbVehicles.append(adsbVehicle);
}
}
}
void ADSBVehicleManager::_tcpError(const QString errorMsg)
{
qgcApp()->showMessage(tr("ADSB Server Error: %1").arg(errorMsg));
}
ADSBTCPLink::ADSBTCPLink(const QString& hostAddress, int port, QObject* parent)
: QThread (parent)
, _hostAddress (hostAddress)
, _port (port)
{
moveToThread(this);
start();
}
ADSBTCPLink::~ADSBTCPLink(void)
{
if (_socket) {
_socket->disconnectFromHost();
_socket->deleteLater();
_socket = nullptr;
}
quit();
wait();
}
void ADSBTCPLink::run(void)
{
_hardwareConnect();
exec();
}
void ADSBTCPLink::_hardwareConnect()
{
_socket = new QTcpSocket();
QObject::connect(_socket, &QTcpSocket::readyRead, this, &ADSBTCPLink::_readBytes);
_socket->connectToHost(_hostAddress, static_cast<quint16>(_port));
// Give the socket a second to connect to the other side otherwise error out
if (!_socket->waitForConnected(1000)) {
qCDebug(ADSBVehicleManagerLog) << "ADSB Socket failed to connect";
emit error(_socket->errorString());
delete _socket;
_socket = nullptr;
return;
}
qCDebug(ADSBVehicleManagerLog) << "ADSB Socket connected";
}
void ADSBTCPLink::_readBytes(void)
{
if (_socket) {
QByteArray bytes = _socket->readLine();
_parseLine(QString::fromLocal8Bit(bytes));
}
}
void ADSBTCPLink::_parseLine(const QString& line)
{
if (line.startsWith(QStringLiteral("MSG"))) {
qCDebug(ADSBVehicleManagerLog) << "ADSB SBS-1" << line;
QStringList values = line.split(QStringLiteral(","));
if (values[1] == QStringLiteral("3")) {
bool icaoOk, altOk, latOk, lonOk;
uint32_t icaoAddress = values[4].toUInt(&icaoOk, 16);
int modeCAltitude = values[11].toInt(&altOk);
double lat = values[14].toDouble(&latOk);
double lon = values[15].toDouble(&lonOk);
QString callsign = values[10];
if (!icaoOk || !altOk || !latOk || !lonOk) {
return;
}
if (lat == 0 && lon == 0) {
return;
}
double altitude = modeCAltitude / 3.048;
QGeoCoordinate location(lat, lon);
ADSBVehicle::VehicleInfo_t adsbInfo;
adsbInfo.icaoAddress = icaoAddress;
adsbInfo.callsign = callsign;
adsbInfo.location = location;
adsbInfo.altitude = altitude;
adsbInfo.availableFlags = ADSBVehicle::CallsignAvailable | ADSBVehicle::LocationAvailable | ADSBVehicle::AltitudeAvailable;
emit adsbVehicleUpdate(adsbInfo);
} else if (values[1] == QStringLiteral("4")) {
bool icaoOk, headingOk;
uint32_t icaoAddress = values[4].toUInt(&icaoOk, 16);
double heading = values[13].toDouble(&headingOk);
if (!icaoOk || !headingOk) {
return;
}
ADSBVehicle::VehicleInfo_t adsbInfo;
adsbInfo.icaoAddress = icaoAddress;
adsbInfo.heading = heading;
adsbInfo.availableFlags = ADSBVehicle::HeadingAvailable;
emit adsbVehicleUpdate(adsbInfo);
} else if (values[1] == QStringLiteral("1")) {
bool icaoOk;
uint32_t icaoAddress = values[4].toUInt(&icaoOk, 16);
if (!icaoOk) {
return;
}
ADSBVehicle::VehicleInfo_t adsbInfo;
adsbInfo.icaoAddress = icaoAddress;
adsbInfo.callsign = values[10];
adsbInfo.availableFlags = ADSBVehicle::CallsignAvailable;
emit adsbVehicleUpdate(adsbInfo);
}
}
}
/****************************************************************************
*
* (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.
*
****************************************************************************/
#pragma once
#include "QGCToolbox.h"
#include "QmlObjectListModel.h"
#include "ADSBVehicle.h"
#include <QThread>
#include <QTcpSocket>
#include <QTimer>
#include <QGeoCoordinate>
class ADSBVehicleManagerSettings;
class ADSBTCPLink : public QThread
{
Q_OBJECT
public:
ADSBTCPLink(const QString& hostAddress, int port, QObject* parent);
~ADSBTCPLink();
signals:
void adsbVehicleUpdate(const ADSBVehicle::VehicleInfo_t vehicleInfo);
void error(const QString errorMsg);
protected:
void run(void) final;
private slots:
void _readBytes(void);
private:
void _hardwareConnect(void);
void _parseLine(const QString& line);
QString _hostAddress;
int _port;
QTcpSocket* _socket = nullptr;
};
class ADSBVehicleManager : public QGCTool {
Q_OBJECT
public:
ADSBVehicleManager(QGCApplication* app, QGCToolbox* toolbox);
Q_PROPERTY(QmlObjectListModel* adsbVehicles READ adsbVehicles CONSTANT)
QmlObjectListModel* adsbVehicles(void) { return &_adsbVehicles; }
// QGCTool overrides
void setToolbox(QGCToolbox* toolbox) final;
public slots:
void adsbVehicleUpdate (const ADSBVehicle::VehicleInfo_t vehicleInfo);
void _tcpError (const QString errorMsg);
private slots:
void _cleanupStaleVehicles(void);
private:
QmlObjectListModel _adsbVehicles;
QMap<uint32_t, ADSBVehicle*> _adsbICAOMap;
QTimer _adsbVehicleCleanupTimer;
ADSBTCPLink* _tcpLink = nullptr;
};
add_library(ADSB
ADSBVehicle.cc
ADSBVehicle.h
ADSBVehicleManager.cc
ADSBVehicleManager.h
)
target_link_libraries(ADSB
PUBLIC
qgc
)
target_include_directories(ADSB
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
......@@ -22,11 +22,12 @@ Item {
anchors.fill: parent
anchors.margins: ScreenTools.defaultFontPixelWidth
property var curVehicle: controller ? controller.activeVehicle : null
property int curMessageIndex:0
property var curMessage: curVehicle && curVehicle.messages.count ? curVehicle.messages.get(curMessageIndex) : null
property int curCompID: 0
property bool selectionValid: false
property var curVehicle: controller ? controller.activeVehicle : null
property int curMessageIndex: 0
property var curMessage: curVehicle && curVehicle.messages.count ? curVehicle.messages.get(curMessageIndex) : null
property int curCompID: 0
property bool selectionValid: false
property real maxButtonWidth: 0
MAVLinkInspectorController {
id: controller
......@@ -76,11 +77,13 @@ Item {
anchors.topMargin: ScreenTools.defaultFontPixelHeight
anchors.bottom: parent.bottom
anchors.left: parent.left
width: buttonCol.width
contentWidth: buttonCol.width
width: maxButtonWidth
contentWidth: width
contentHeight: buttonCol.height
ColumnLayout {
id: buttonCol
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelHeight * 0.25
Repeater {
model: curVehicle ? curVehicle.messages : []
......@@ -94,7 +97,7 @@ Item {
selectionValid = true
curMessageIndex = index
}
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 40
Layout.fillWidth: true
}
}
}
......
......@@ -111,7 +111,7 @@ const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
_components.append(QVariant::fromValue((VehicleComponent*)_followComponent));
}
if (_vehicle->vehicleType() == MAV_TYPE_HELICOPTER) {
if (_vehicle->vehicleType() == MAV_TYPE_HELICOPTER && (_vehicle->versionCompare(4, 0, 0) >= 0)) {
_heliComponent = new APMHeliComponent(_vehicle, this);
_heliComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_heliComponent));
......
......@@ -37,35 +37,43 @@ SetupPage {
property real _margins: ScreenTools.defaultFontPixelHeight
property bool _showIcon: !ScreenTools.isTinyScreen
property Fact _hSvMan: controller.getParameterFact(-1, "H_SV_MAN")
property Fact _hSv1Pos: controller.getParameterFact(-1, "H_SV1_POS")
property Fact _hSv2Pos: controller.getParameterFact(-1, "H_SV2_POS")
property Fact _hSv3Pos: controller.getParameterFact(-1, "H_SV3_POS")
property Fact _hSwashType: controller.getParameterFact(-1, "H_SWASH_TYPE")
property Fact _hColCtrlDir: controller.getParameterFact(-1, "H_COL_CTRL_DIR")
property Fact _hFlybarMode: controller.getParameterFact(-1, "H_FLYBAR_MODE")
property Fact _hColMax: controller.getParameterFact(-1, "H_COL_MAX")
property Fact _hColMid: controller.getParameterFact(-1, "H_COL_MID")
property Fact _hColMin: controller.getParameterFact(-1, "H_COL_MIN")
property Fact _hCycMax: controller.getParameterFact(-1, "H_CYC_MAX")
property Fact _hSvMan: controller.getParameterFact(-1, "H_SV_MAN")
property Fact _hSwType: controller.getParameterFact(-1, "H_SW_TYPE")
property Fact _hSwColDir: controller.getParameterFact(-1, "H_SW_COL_DIR")
property Fact _hSwLinSvo: controller.getParameterFact(-1, "H_SW_LIN_SVO")
property Fact _hFlybarMode: controller.getParameterFact(-1, "H_FLYBAR_MODE")
property Fact _hColMax: controller.getParameterFact(-1, "H_COL_MAX")
property Fact _hColMid: controller.getParameterFact(-1, "H_COL_MID")
property Fact _hColMin: controller.getParameterFact(-1, "H_COL_MIN")
property Fact _hCycMax: controller.getParameterFact(-1, "H_CYC_MAX")
property Fact _hRscMode: controller.getParameterFact(-1, "H_RSC_MODE")
property Fact _hRscCritical: controller.getParameterFact(-1, "H_RSC_CRITICAL")
property Fact _hRscIdle: controller.getParameterFact(-1, "H_RSC_IDLE")
property Fact _hRscRampTime: controller.getParameterFact(-1, "H_RSC_RAMP_TIME")
property Fact _hRscRunupTime: controller.getParameterFact(-1, "H_RSC_RUNUP_TIME")
property Fact _hRscSetpoint: controller.getParameterFact(-1, "H_RSC_SETPOINT")
property Fact _hRscIdle: controller.getParameterFact(-1, "H_RSC_IDLE")
property Fact _hRscThrcrv0: controller.getParameterFact(-1, "H_RSC_THRCRV_0")
property Fact _hRscThrcrv25: controller.getParameterFact(-1, "H_RSC_THRCRV_25")
property Fact _hRscThrcrv50: controller.getParameterFact(-1, "H_RSC_THRCRV_50")
property Fact _hRscThrcrv75: controller.getParameterFact(-1, "H_RSC_THRCRV_75")
property Fact _hRscThrcrv100: controller.getParameterFact(-1, "H_RSC_THRCRV_100")
property Fact _hLandColMin: controller.getParameterFact(-1, "H_LAND_COL_MIN")
property Fact _hRscGovSetpnt: controller.getParameterFact(-1, "H_RSC_GOV_SETPNT")
property Fact _hRscGovDisgag: controller.getParameterFact(-1, "H_RSC_GOV_DISGAG")
property Fact _hRscGovDroop: controller.getParameterFact(-1, "H_RSC_GOV_DROOP")
property Fact _hRscGovTcgain: controller.getParameterFact(-1, "H_RSC_GOV_TCGAIN")
property Fact _hRscGovRange: controller.getParameterFact(-1, "H_RSC_GOV_RANGE")
property Fact _imStabCol1: controller.getParameterFact(-1, "IM_STAB_COL_1")
property Fact _imStabCol2: controller.getParameterFact(-1, "IM_STAB_COL_2")
property Fact _imStabCol3: controller.getParameterFact(-1, "IM_STAB_COL_3")
property Fact _imStabCol4: controller.getParameterFact(-1, "IM_STAB_COL_4")
property Fact _hTailType: controller.getParameterFact(-1, "H_TAIL_TYPE")
property Fact _hTailSpeed: controller.getParameterFact(-1, "H_TAIL_SPEED")
property Fact _hGyrGain: controller.getParameterFact(-1, "H_GYR_GAIN")
property Fact _hGyrGainAcro: controller.getParameterFact(-1, "H_GYR_GAIN_ACRO")
property Fact _hColYaw: controller.getParameterFact(-1, "H_COLYAW")
QGCGroupBox {
title: qsTr("Servo Setup")
......@@ -267,7 +275,7 @@ SetupPage {
}
QGCGroupBox {
title: qsTr("Swash Setup")
title: qsTr("Swashplate Setup")
GridLayout {
columns: 2
......@@ -278,24 +286,21 @@ SetupPage {
indexModel: false
}
QGCLabel { text: _hSv1Pos.shortDescription }
FactTextField { fact: _hSv1Pos }
QGCLabel { text: _hSv2Pos.shortDescription }
FactTextField { fact: _hSv2Pos }
QGCLabel { text: _hSv3Pos.shortDescription }
FactTextField { fact: _hSv3Pos }
QGCLabel { text: _hSwType.shortDescription }
FactComboBox {
fact: _hSwType
indexModel: false
}
QGCLabel { text: _hSwashType.shortDescription }
QGCLabel { text: _hSwColDir.shortDescription }
FactComboBox {
fact: _hSwashType
fact: _hSwColDir
indexModel: false
}
QGCLabel { text: _hColCtrlDir.shortDescription }
QGCLabel { text: _hSwLinSvo.shortDescription }
FactComboBox {
fact: _hColCtrlDir
fact: _hSwLinSvo
indexModel: false
}
......@@ -320,7 +325,7 @@ SetupPage {
}
QGCGroupBox {
title: qsTr("Throttle Setup")
title: qsTr("Throttle Settings")
GridLayout {
columns: 2
......@@ -334,9 +339,6 @@ SetupPage {
QGCLabel { text: _hRscCritical.shortDescription }
FactTextField { fact: _hRscCritical }
QGCLabel { text: _hRscIdle.shortDescription }
FactTextField { fact: _hRscIdle }
QGCLabel { text: _hRscRampTime.shortDescription }
FactTextField { fact: _hRscRampTime }
......@@ -346,6 +348,9 @@ SetupPage {
QGCLabel { text: _hRscSetpoint.shortDescription }
FactTextField { fact: _hRscSetpoint }
QGCLabel { text: _hRscIdle.shortDescription }
FactTextField { fact: _hRscIdle }
QGCLabel { text: _hRscThrcrv0.shortDescription }
FactTextField { fact: _hRscThrcrv0 }
......@@ -364,13 +369,36 @@ SetupPage {
}
QGCGroupBox {
title: qsTr("Collective Curve Setup")
title: qsTr("Governor Settings")
GridLayout {
columns: 2
QGCLabel { text: _hLandColMin.shortDescription }
FactTextField { fact: _hLandColMin }
QGCLabel { text: _hRscGovSetpnt.shortDescription }
FactTextField { fact: _hRscGovSetpnt }
QGCLabel { text: _hRscGovDisgag.shortDescription }
FactTextField { fact: _hRscGovDisgag }
QGCLabel { text: _hRscGovDroop.shortDescription }
FactTextField { fact: _hRscGovDroop }
QGCLabel { text: _hRscGovTcgain.shortDescription }
FactTextField { fact: _hRscGovTcgain }
QGCLabel { text: _hRscGovRange.shortDescription }
FactTextField { fact: _hRscGovRange }
}
}
QGCGroupBox {
title: qsTr("Miscellaneous Settings")
GridLayout {
columns: 2
QGCLabel { text: qsTr("* Stabilize Collective Curve *") }
QGCLabel { text: qsTr("") }
QGCLabel { text: _imStabCol1.shortDescription }
FactTextField { fact: _imStabCol1 }
......@@ -383,6 +411,27 @@ SetupPage {
QGCLabel { text: _imStabCol4.shortDescription }
FactTextField { fact: _imStabCol4 }
QGCLabel { text: qsTr("* Tail & Gyros *") }
QGCLabel { text: qsTr("") }
QGCLabel { text: _hTailType.shortDescription }
FactComboBox {
fact: _hTailType
indexModel: false
}
QGCLabel { text: _hTailSpeed.shortDescription }
FactTextField { fact: _hTailSpeed }
QGCLabel { text: _hGyrGain.shortDescription }
FactTextField { fact: _hGyrGain }
QGCLabel { text: _hGyrGainAcro.shortDescription }
FactTextField { fact: _hGyrGainAcro }
QGCLabel { text: _hColYaw.shortDescription }
FactTextField { fact: _hColYaw }
}
}
} // Flow
......
......@@ -64,7 +64,9 @@ SetupPage {
ExclusiveGroup { id: returnAltRadioGroup }
Component.onCompleted: {
showAdvanced = !ScreenTools.isMobile
// Advanced tuning is hacked out due to Qt crash with Qml Charts and a QGuiApplication
//showAdvanced = !ScreenTools.isMobile
// Qml Sliders have a strange behavior in which they first set Slider::value to some internal
// setting and then set Slider::value to the bound properties value. If you have an onValueChanged
// handler which updates your property with the new value, this first value change will trash
......
......@@ -439,6 +439,11 @@
<output name="MAIN3">motor 3</output>
<output name="MAIN4">motor 4</output>
</airframe>
<airframe id="4500" maintainer="Oleg Kalachev &lt;okalachev@gmail.com&gt;" name="COEX Clover 4">
<class>Copter</class>
<maintainer>Oleg Kalachev &lt;okalachev@gmail.com&gt;</maintainer>
<type>Quadrotor x</type>
</airframe>
<airframe id="4900" maintainer="Dennis Shtatov &lt;densht@gmail.com&gt;" name="Crazyflie 2">
<class>Copter</class>
<maintainer>Dennis Shtatov &lt;densht@gmail.com&gt;</maintainer>
......
......@@ -81,52 +81,49 @@ Item {
height: flightModeColumn.height + ScreenTools.defaultFontPixelHeight
color: qgcPal.windowShade
ColumnLayout {
GridLayout {
id: flightModeColumn
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.left: parent.left
anchors.top: parent.top
spacing: ScreenTools.defaultFontPixelHeight
rows: 7
rowSpacing: ScreenTools.defaultFontPixelWidth / 2
columnSpacing: rowSpacing
flow: GridLayout.TopToBottom
RowLayout {
QGCLabel {
Layout.fillWidth: true
spacing: _margins
text: qsTr("Mode Channel")
}
Repeater {
model: 6
QGCLabel {
Layout.fillWidth: true
text: qsTr("Mode channel:")
text: qsTr("Flight Mode %1").arg(modelData + 1)
color: controller.activeFlightMode == index ? "yellow" : qgcPal.text
}
}
FactComboBox {
Layout.preferredWidth: _channelComboWidth
fact: controller.getParameterFact(-1, "RC_MAP_FLTMODE")
indexModel: false
}
FactComboBox {
Layout.fillWidth: true
fact: controller.getParameterFact(-1, "RC_MAP_FLTMODE")
indexModel: false
sizeToContents: true
}
Repeater {
model: 6
RowLayout {
FactComboBox {
Layout.fillWidth: true
spacing: ScreenTools.defaultFontPixelWidth
property int index: modelData + 1
QGCLabel {
Layout.fillWidth: true
text: qsTr("Flight Mode %1").arg(index)
color: controller.activeFlightMode == index ? "yellow" : qgcPal.text
}
FactComboBox {
Layout.preferredWidth: _channelComboWidth
fact: controller.getParameterFact(-1, "COM_FLTMODE" + index)
indexModel: false
}
fact: controller.getParameterFact(-1, "COM_FLTMODE" + (modelData + 1))
indexModel: false
sizeToContents: true
}
} // Repeater - Flight Modes
} // Column - Flight Modes
}
}
} // Rectangle - Flight Modes
} // Column - Flight mode settings
......
......@@ -29,7 +29,8 @@ SetupPage {
width: availableWidth
Component.onCompleted: {
showAdvanced = !ScreenTools.isMobile
// Advanced tuning is hacked out due to Qt crash with Qml Charts and a QGuiApplication
//showAdvanced = !ScreenTools.isMobile
}
FactPanelController {
......
......@@ -29,7 +29,8 @@ SetupPage {
width: availableWidth
Component.onCompleted: {
showAdvanced = !ScreenTools.isMobile
// Advanced tuning is hacked out due to Qt crash with Qml Charts and a QGuiApplication
//showAdvanced = !ScreenTools.isMobile
}
FactPanelController {
......
......@@ -113,6 +113,7 @@ set_source_files_properties(QGCApplication.cc PROPERTIES COMPILE_DEFINITIONS GIT
add_subdirectory(ui)
add_subdirectory(ADSB)
add_subdirectory(Airmap)
add_subdirectory(AnalyzeView)
add_subdirectory(api)
......@@ -148,6 +149,7 @@ target_link_libraries(qgc
Qt5::QuickWidgets
Qt5::Widgets
ADSB
Airmap
AnalyzeView
api
......
......@@ -203,7 +203,7 @@ QGCCameraManager::_findCamera(int id)
}
}
}
qWarning() << "Camera component id not found:" << id;
//qWarning() << "Camera component id not found:" << id;
return nullptr;
}
......
This diff is collapsed.
......@@ -39,6 +39,7 @@ public:
Q_PROPERTY(bool parametersReady READ parametersReady NOTIFY parametersReadyChanged) ///< true: Parameters are ready for use
Q_PROPERTY(bool missingParameters READ missingParameters NOTIFY missingParametersChanged) ///< true: Parameters are missing from firmware response, false: all parameters received from firmware
Q_PROPERTY(double loadProgress READ loadProgress NOTIFY loadProgressChanged)
Q_PROPERTY(bool pendingWrites READ pendingWrites NOTIFY pendingWritesChanged) ///< true: There are still pending write updates against the vehicle
bool parametersReady (void) const { return _parametersReady; }
bool missingParameters (void) const { return _missingParameters; }
......@@ -56,7 +57,7 @@ public:
void refreshAllParameters(uint8_t componentID = MAV_COMP_ID_ALL);
/// Request a refresh on the specific parameter
void refreshParameter(int componentId, const QString& name);
void refreshParameter(int componentId, const QString& paramName);
/// Request a refresh on all parameters that begin with the specified prefix
void refreshParametersPrefix(int componentId, const QString& namePrefix);
......@@ -67,7 +68,7 @@ public:
/// Returns true if the specifed parameter exists
/// @param componentId Component id or FactSystem::defaultComponentId
/// @param name Parameter name
bool parameterExists(int componentId, const QString& name);
bool parameterExists(int componentId, const QString& paramName);
/// Returns all parameter names
QStringList parameterNames(int componentId);
......@@ -76,14 +77,16 @@ public:
/// a missing parameter error to user if parameter does not exist.
/// @param componentId Component id or FactSystem::defaultComponentId
/// @param name Parameter name
Fact* getParameter(int componentId, const QString& name);
Fact* getParameter(int componentId, const QString& paramName);
const QMap<QString, QMap<QString, QStringList> >& getDefaultComponentCategoryMap(void);
int getComponentId(const QString& category);
QString getComponentCategory(int componentId);
const QMap<QString, QMap<QString, QStringList> >& getComponentCategoryMap(int componentId);
/// Returns error messages from loading
QString readParametersFromStream(QTextStream& stream);
void writeParametersToStream(QTextStream &stream);
void writeParametersToStream(QTextStream& stream);
/// Returns the version number for the parameter set, -1 if not known
int parameterSetVersion(void) { return _parameterSetMajorVersion; }
......@@ -111,12 +114,15 @@ public:
/// @return true: success, false: failure (errorString set)
bool loadFromJson(const QJsonObject& json, bool required, QString& errorString);
bool pendingWrites(void);
Vehicle* vehicle(void) { return _vehicle; }
signals:
void parametersReadyChanged(bool parametersReady);
void missingParametersChanged(bool missingParameters);
void loadProgressChanged(float value);
void parametersReadyChanged (bool parametersReady);
void missingParametersChanged (bool missingParameters);
void loadProgressChanged (float value);
void pendingWritesChanged (bool pendingWrites);
protected:
Vehicle* _vehicle;
......@@ -133,6 +139,7 @@ private:
static FirmwarePlugin* _anyVehicleTypeFirmwarePlugin(MAV_AUTOPILOT firmwareType);
int _actualComponentId(int componentId);
void _setupComponentCategoryMap(int componentId);
void _setupDefaultComponentCategoryMap(void);
void _readParameterRaw(int componentId, const QString& paramName, int paramIndex);
void _writeParameterRaw(int componentId, const QString& paramName, const QVariant& value);
......@@ -146,6 +153,7 @@ private:
QString _logVehiclePrefix(int componentId);
void _setLoadProgress(double loadProgress);
bool _fillIndexBatchQueue(bool waitingParamTimeout);
void _updateProgressBar(void);
MAV_PARAM_TYPE _factTypeToMavType(FactMetaData::ValueType_t factType);
FactMetaData::ValueType_t _mavTypeToFactType(MAV_PARAM_TYPE mavType);
......@@ -155,8 +163,10 @@ private:
/// Second mapping is parameter name, to Fact* in QVariant
QMap<int, QVariantMap> _mapParameterName2Variant;
// Category map of default component parameters
QMap<QString /* category */, QMap<QString /* group */, QStringList /* parameter names */> > _defaultComponentCategoryMap;
// List of category map of component parameters
typedef QMap<QString, QMap<QString, QStringList>> ComponentCategoryMapType; //<Key: category, Value: Map< Key: group, Value: parameter names list >>
QMap<int, ComponentCategoryMapType> _componentCategoryMaps;
QHash<QString, int> _componentCategoryHash;
double _loadProgress; ///< Parameter load progess, [0.0,1.0]
bool _parametersReady; ///< true: parameter load complete
......@@ -178,9 +188,13 @@ private:
QMap<int /* component id */, QMap<QString /* param name */, bool /* seen */>> _debugCacheParamSeen;
// Wait counts from previous parameter update cycle
int _prevWaitingReadParamIndexCount;
int _prevWaitingReadParamNameCount;
int _prevWaitingWriteParamNameCount;
int _prevWaitingReadParamIndexCount;
int _prevWaitingReadParamNameCount;
int _prevWaitingWriteParamNameCount;
bool _readParamIndexProgressActive = false;
bool _readParamNameProgressActive = false;
bool _writeParamProgressActive = false;
static const int _maxInitialRequestListRetry = 4; ///< Maximum retries for request list
int _initialRequestRetryCount; ///< Current retry count for request list
......@@ -197,7 +211,9 @@ private:
QMap<int, QMap<QString, int> > _waitingWriteParamNameMap; ///< Key: Component id, Value: Map { Key: parameter name still waiting for, Value: retry count }
QMap<int, QList<int> > _failedReadParamIndexMap; ///< Key: Component id, Value: failed parameter index
int _totalParamCount; ///< Number of parameters across all components
int _totalParamCount; ///< Number of parameters across all components
int _waitingWriteParamBatchCount = 0; ///< Number of parameters which are batched up waiting on write responses
int _waitingReadParamNameBatchCount = 0; ///< Number of parameters which are batched up waiting on read responses
QTimer _initialRequestTimeoutTimer;
QTimer _waitingParamTimeoutTimer;
......
......@@ -129,6 +129,13 @@ QString APMParameterMetaData::mavTypeToString(MAV_TYPE vehicleTypeEnum)
return vehicleName;
}
QString APMParameterMetaData::_groupFromParameterName(const QString& name)
{
QString group = name.split('_').first();
return group.remove(QRegExp("[0-9]*$")); // remove any numbers from the end
}
void APMParameterMetaData::loadParameterFactMetaDataFile(const QString& metaDataFile)
{
if (_parameterMetaDataLoaded) {
......@@ -232,8 +239,7 @@ void APMParameterMetaData::loadParameterFactMetaDataFile(const QString& metaData
if (name.contains(':')) {
name = name.split(':').last();
}
QString group = name.split('_').first();
group = group.remove(QRegExp("[0-9]*$")); // remove any numbers from the end
QString group = _groupFromParameterName(name);
QString category = xml.attributes().value("user").toString();
if (category.isEmpty()) {
......@@ -435,6 +441,8 @@ void APMParameterMetaData::addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType)
// we don't have data for this fact
if (!rawMetaData) {
metaData->setCategory(QStringLiteral("Advanced"));
metaData->setGroup(_groupFromParameterName(fact->name()));
fact->setMetaData(metaData);
qCDebug(APMParameterMetaDataLog) << "No metaData for " << fact->name() << "using generic metadata";
return;
......
......@@ -80,6 +80,7 @@ private:
bool parseParameterAttributes(QXmlStreamReader& xml, APMFactMetaDataRaw *rawMetaData);
void correctGroupMemberships(ParameterNametoFactMetaDataMap& parameterToFactMetaDataMap, QMap<QString,QStringList>& groupMembers);
QString mavTypeToString(MAV_TYPE vehicleTypeEnum);
QString _groupFromParameterName(const QString& name);
bool _parameterMetaDataLoaded; ///< true: parameter meta data already loaded
QMap<QString, ParameterNametoFactMetaDataMap> _vehicleTypeToParametersMap; ///< Maps from a vehicle type to paramametertoFactMeta map>
......
......@@ -214,8 +214,7 @@ FlightMap {
// Add ADSB vehicles to the map
MapItemView {
model: activeVehicle ? activeVehicle.adsbVehicles : []
property var activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
model: QGroundControl.adsbVehicleManager.adsbVehicles
delegate: VehicleMapItem {
coordinate: object.coordinate
altitude: object.altitude
......
......@@ -36,7 +36,7 @@ Item {
readonly property string emergencyStopTitle: qsTr("EMERGENCY STOP")
readonly property string armTitle: qsTr("Arm")
readonly property string disarmTitle: qsTr("Disarm")
readonly property string rtlTitle: qsTr("RTL")
readonly property string rtlTitle: qsTr("Return")
readonly property string takeoffTitle: qsTr("Takeoff")
readonly property string landTitle: qsTr("Land")
readonly property string startMissionTitle: qsTr("Start Mission")
......
......@@ -32,7 +32,6 @@ MapQuickItem {
id: _label
checked: _isCurrentItem
label: missionItem ? missionItem.abbreviation : ""
//index: missionItem ? missionItem.sequenceNumber : 0
gimbalYaw: missionItem.missionGimbalYaw
vehicleYaw: missionItem.missionVehicleYaw
showGimbalYaw: !isNaN(missionItem.missionGimbalYaw)
......
......@@ -23,7 +23,6 @@ Rectangle {
height: _itemIndicatorHeight + (_touchMarginVertical * 2)
color: "transparent"
z: QGroundControl.zOrderMapItems + 1 // Above item icons
visible: itemCoordinate.isValid
// Properties which must be specific by consumer
property var mapControl ///< Map control which contains this item
......
......@@ -17,8 +17,6 @@ import QGroundControl.Palette 1.0
/// The MissionLineView control is used to add lines between mission items
MapItemView {
property bool homePositionValid: true ///< true: show home position, false: don't show home position
delegate: MapPolyline {
line.width: 3
line.color: "#be781c" // Hack, can't get palette to work in here
......
......@@ -80,7 +80,7 @@ MapQuickItem {
anchors.horizontalCenter: parent.horizontalCenter
map: _map
text: vehicleLabelText
font.pointSize: ScreenTools.smallFontPointSize
font.pointSize: _adsbVehicle ? ScreenTools.defaultFontPointSize : ScreenTools.smallFontPointSize
visible: _adsbVehicle ? !isNaN(altitude) : _multiVehicle
property string vehicleLabelText: visible ?
(_adsbVehicle ?
......@@ -89,15 +89,5 @@ MapQuickItem {
""
}
QGCMapLabel {
anchors.top: vehicleLabel.bottom
anchors.horizontalCenter: parent.horizontalCenter
map: _map
text: vehicleLabelText
font.pointSize: ScreenTools.smallFontPointSize
visible: _adsbVehicle ? !isNaN(altitude) : _multiVehicle
property string vehicleLabelText: visible && _adsbVehicle ? callsign : ""
}
}
}
/****************************************************************************
*
* (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 "BlankPlanCreator.h"
#include "PlanMasterController.h"
#include "MissionSettingsItem.h"
#include "FixedWingLandingComplexItem.h"
BlankPlanCreator::BlankPlanCreator(PlanMasterController* planMasterController, QObject* parent)
: PlanCreator(planMasterController, tr("Blank"), QStringLiteral("/qmlimages/PlanCreator/BlankPlanCreator.png"), parent)
{
}
void BlankPlanCreator::createPlan(const QGeoCoordinate& /*mapCenterCoord*/)
{
_planMasterController->removeAll();
}
......@@ -11,12 +11,12 @@
#include "PlanCreator.h"
class CustomPlanCreator : public PlanCreator
class BlankPlanCreator : public PlanCreator
{
Q_OBJECT
public:
CustomPlanCreator(PlanMasterController* planMasterController, QObject* parent = nullptr);
BlankPlanCreator(PlanMasterController* planMasterController, QObject* parent = nullptr);
Q_INVOKABLE void createPlan(const QGeoCoordinate& mapCenterCoord) final;
};
......@@ -3,67 +3,128 @@ set(EXTRA_SRC)
if(BUILD_TESTING)
list(APPEND EXTRA_SRC
CameraCalcTest.cc
CameraCalcTest.h
CameraSectionTest.cc
CameraSectionTest.h
CorridorScanComplexItemTest.cc
CorridorScanComplexItemTest.h
FWLandingPatternTest.cc
FWLandingPatternTest.h
MissionCommandTreeTest.cc
MissionCommandTreeTest.h
MissionControllerManagerTest.cc
MissionControllerManagerTest.h
MissionControllerTest.cc
MissionControllerTest.h
MissionItemTest.cc
MissionItemTest.h
MissionManagerTest.cc
MissionManagerTest.h
MissionSettingsTest.cc
MissionSettingsTest.h
PlanMasterControllerTest.cc
PlanMasterControllerTest.h
QGCMapPolygonTest.cc
QGCMapPolygonTest.h
QGCMapPolylineTest.cc
QGCMapPolylineTest.h
SectionTest.cc
SectionTest.h
SimpleMissionItemTest.cc
SimpleMissionItemTest.h
SpeedSectionTest.cc
SpeedSectionTest.h
StructureScanComplexItemTest.cc
StructureScanComplexItemTest.h
SurveyComplexItemTest.cc
SurveyComplexItemTest.h
TransectStyleComplexItemTest.cc
TransectStyleComplexItemTest.h
VisualMissionItemTest.cc
VisualMissionItemTest.h
)
endif()
add_library(MissionManager
BlankPlanCreator.cc
BlankPlanCreator.h
CameraCalc.cc
CameraCalc.h
CameraSection.cc
CameraSection.h
CameraSpec.cc
CameraSpec.h
ComplexMissionItem.cc
ComplexMissionItem.h
CorridorScanComplexItem.cc
CorridorScanComplexItem.h
CorridorScanPlanCreator.cc
CustomPlanCreator.cc
CorridorScanPlanCreator.h
FixedWingLandingComplexItem.cc
FixedWingLandingComplexItem.h
GeoFenceController.cc
GeoFenceController.h
GeoFenceManager.cc
GeoFenceManager.h
KML.cc
KML.h
MissionCommandList.cc
MissionCommandList.h
MissionCommandTree.cc
MissionCommandTree.h
MissionCommandUIInfo.cc
MissionCommandUIInfo.h
MissionController.cc
MissionController.h
MissionItem.cc
MissionItem.h
MissionManager.cc
MissionManager.h
MissionSettingsItem.cc
MissionSettingsItem.h
PlanCreator.cc
PlanCreator.h
PlanElementController.cc
PlanElementController.h
PlanManager.cc
PlanManager.h
PlanMasterController.cc
PlanMasterController.h
QGCFenceCircle.cc
QGCFenceCircle.h
QGCFencePolygon.cc
QGCFencePolygon.h
QGCMapCircle.cc
QGCMapCircle.h
QGCMapPolygon.cc
QGCMapPolygon.h
QGCMapPolyline.cc
QGCMapPolyline.h
RallyPoint.cc
RallyPointController.cc
RallyPointController.h
RallyPoint.h
RallyPointManager.cc
RallyPointManager.h
Section.h
SimpleMissionItem.cc
SimpleMissionItem.h
SpeedSection.cc
SpeedSection.h
StructureScanComplexItem.cc
StructureScanComplexItem.h
StructureScanPlanCreator.cc
StructureScanPlanCreator.h
SurveyComplexItem.cc
SurveyComplexItem.h
SurveyPlanCreator.cc
SurveyPlanCreator.h
TakeoffMissionItem.cc
TakeoffMissionItem.h
TransectStyleComplexItem.cc
TransectStyleComplexItem.h
VisualMissionItem.cc
VisualMissionItem.h
Section.h # shouldn't be listed here, but isn't named properly for AUTOMOC
......
......@@ -21,16 +21,8 @@ CorridorScanPlanCreator::CorridorScanPlanCreator(PlanMasterController* planMaste
void CorridorScanPlanCreator::createPlan(const QGeoCoordinate& mapCenterCoord)
{
_planMasterController->removeAll();
VisualMissionItem* takeoffItem = _missionController->insertSimpleMissionItem(mapCenterCoord, -1);
takeoffItem->setWizardMode(true);
_missionController->insertComplexMissionItem(MissionController::patternCorridorScanName, mapCenterCoord, -1)->setWizardMode(true);
if (_planMasterController->managerVehicle()->fixedWing()) {
FixedWingLandingComplexItem* landingItem = qobject_cast<FixedWingLandingComplexItem*>(_missionController->insertComplexMissionItem(MissionController::patternFWLandingName, mapCenterCoord, -1));
landingItem->setWizardMode(true);
landingItem->setLoiterDragAngleOnly(true);
} else {
MissionSettingsItem* settingsItem = _missionController->visualItems()->value<MissionSettingsItem*>(0);
settingsItem->setMissionEndRTL(true);
}
VisualMissionItem* takeoffItem = _missionController->insertTakeoffItem(mapCenterCoord, -1);
_missionController->insertComplexMissionItem(MissionController::patternCorridorScanName, mapCenterCoord, -1);
_missionController->insertLandItem(mapCenterCoord, -1);
_missionController->setCurrentPlanViewIndex(takeoffItem->sequenceNumber(), true);
}
/****************************************************************************
*
* (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 "CustomPlanCreator.h"
#include "PlanMasterController.h"
#include "MissionSettingsItem.h"
#include "FixedWingLandingComplexItem.h"
CustomPlanCreator::CustomPlanCreator(PlanMasterController* planMasterController, QObject* parent)
: PlanCreator(planMasterController, tr("Custom"), QStringLiteral("/qmlimages/PlanCreator/CustomPlanCreator.png"), parent)
{
}
void CustomPlanCreator::createPlan(const QGeoCoordinate& mapCenterCoord)
{
_planMasterController->removeAll();
VisualMissionItem* takeoffItem = _missionController->insertSimpleMissionItem(mapCenterCoord, -1);
takeoffItem->setWizardMode(true);
_missionController->insertSimpleMissionItem(mapCenterCoord.atDistanceAndAzimuth(50, 135), -1);
_missionController->insertSimpleMissionItem(mapCenterCoord.atDistanceAndAzimuth(50, -135),-1);
if (_planMasterController->managerVehicle()->fixedWing()) {
FixedWingLandingComplexItem* landingItem = qobject_cast<FixedWingLandingComplexItem*>(_missionController->insertComplexMissionItem(MissionController::patternFWLandingName, mapCenterCoord, -1));
landingItem->setWizardMode(true);
landingItem->setLoiterDragAngleOnly(true);
} else {
MissionSettingsItem* settingsItem = _missionController->visualItems()->value<MissionSettingsItem*>(0);
settingsItem->setMissionEndRTL(true);
}
_missionController->setCurrentPlanViewIndex(takeoffItem->sequenceNumber(), true);
}
......@@ -219,7 +219,7 @@ const MissionCommandUIInfo* MissionCommandTree::getUIInfo(Vehicle* vehicle, MAV_
}
}
QVariantList MissionCommandTree::getCommandsForCategory(Vehicle* vehicle, const QString& category)
QVariantList MissionCommandTree::getCommandsForCategory(Vehicle* vehicle, const QString& category, bool showFlyThroughCommands)
{
MAV_AUTOPILOT baseFirmwareType;
MAV_TYPE baseVehicleType;
......@@ -237,7 +237,8 @@ QVariantList MissionCommandTree::getCommandsForCategory(Vehicle* vehicle, const
for (MAV_CMD command: commandMap.keys()) {
if (supportedCommands.contains(command)) {
MissionCommandUIInfo* uiInfo = commandMap[command];
if (uiInfo->category() == category || category == _allCommandsCategory) {
if ((uiInfo->category() == category || category == _allCommandsCategory) &&
(showFlyThroughCommands || !uiInfo->specifiesCoordinate() || uiInfo->isStandaloneCoordinate())) {
list.append(QVariant::fromValue(uiInfo));
}
}
......
......@@ -62,7 +62,8 @@ public:
const MissionCommandUIInfo* getUIInfo(Vehicle* vehicle, MAV_CMD command);
Q_INVOKABLE QVariantList getCommandsForCategory(Vehicle* vehicle, const QString& category);
/// @param showFlyThroughCommands - true: al commands shows, false: filter out commands which the vehicle flies through (specifiedCoordinate=true, standaloneCoordinate=false)
Q_INVOKABLE QVariantList getCommandsForCategory(Vehicle* vehicle, const QString& category, bool showFlyThroughCommands);
// Overrides from QGCTool
virtual void setToolbox(QGCToolbox* toolbox);
......
This diff is collapsed.
This diff is collapsed.
......@@ -111,51 +111,6 @@ void MissionControllerTest::_testEmptyVehicleAPM(void)
_testEmptyVehicleWorker(MAV_AUTOPILOT_ARDUPILOTMEGA);
}
void MissionControllerTest::_testAddWaypointWorker(MAV_AUTOPILOT firmwareType)
{
_initForFirmwareType(firmwareType);
QGeoCoordinate coordinate(37.803784, -122.462276);
_missionController->insertSimpleMissionItem(coordinate, _missionController->visualItems()->count());
QmlObjectListModel* visualItems = _missionController->visualItems();
QVERIFY(visualItems);
QCOMPARE(visualItems->count(), 2);
MissionSettingsItem* settingsItem = visualItems->value<MissionSettingsItem*>(0);
SimpleMissionItem* simpleItem = visualItems->value<SimpleMissionItem*>(1);
QVERIFY(settingsItem);
QVERIFY(simpleItem);
QCOMPARE((MAV_CMD)simpleItem->command(), MAV_CMD_NAV_TAKEOFF);
QCOMPARE(simpleItem->childItems()->count(), 0);
// Planned home position should always be set after first item
QVERIFY(settingsItem->coordinate().isValid());
// ArduPilot takeoff command has no coordinate, so should be child item
QCOMPARE(settingsItem->childItems()->count(), firmwareType == MAV_AUTOPILOT_ARDUPILOTMEGA ? 1 : 0);
// Check waypoint line from home to takeoff
int expectedLineCount = firmwareType == MAV_AUTOPILOT_ARDUPILOTMEGA ? 0 : 1;
QmlObjectListModel* waypointLines = _missionController->waypointLines();
QVERIFY(waypointLines);
QCOMPARE(waypointLines->count(), expectedLineCount);
}
void MissionControllerTest::_testAddWayppointAPM(void)
{
_testAddWaypointWorker(MAV_AUTOPILOT_ARDUPILOTMEGA);
}
void MissionControllerTest::_testAddWayppointPX4(void)
{
_testAddWaypointWorker(MAV_AUTOPILOT_PX4);
}
#if 0
void MissionControllerTest::_testOfflineToOnlineWorker(MAV_AUTOPILOT firmwareType)
{
......
......@@ -36,8 +36,6 @@ private slots:
void _testLoadJsonSectionAvailable(void);
void _testEmptyVehicleAPM(void);
void _testEmptyVehiclePX4(void);
void _testAddWayppointAPM(void);
void _testAddWayppointPX4(void);
private:
#if 0
......
/****************************************************************************
*
* (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 MissionController_H
#define MissionController_H
#include "PlanElementController.h"
#include "QmlObjectListModel.h"
#include "Vehicle.h"
#include "QGCLoggingCategory.h"
#include "MavlinkQmlSingleton.h"
#include "VisualMissionItem.h"
#include <QHash>
class CoordinateVector;
Q_DECLARE_LOGGING_CATEGORY(MissionControllerLog)
typedef QPair<VisualMissionItem*,VisualMissionItem*> VisualItemPair;
typedef QHash<VisualItemPair, CoordinateVector*> CoordVectHashTable;
class MissionController : public PlanElementController
{
Q_OBJECT
public:
MissionController(QObject* parent = NULL);
~MissionController();
Q_PROPERTY(QGeoCoordinate plannedHomePosition READ plannedHomePosition NOTIFY plannedHomePositionChanged)
Q_PROPERTY(QmlObjectListModel* visualItems READ visualItems NOTIFY visualItemsChanged)
Q_PROPERTY(QmlObjectListModel* complexVisualItems READ complexVisualItems NOTIFY complexVisualItemsChanged)
Q_PROPERTY(QmlObjectListModel* waypointLines READ waypointLines NOTIFY waypointLinesChanged)
Q_PROPERTY(double missionDistance READ missionDistance NOTIFY missionDistanceChanged)
Q_PROPERTY(double missionTime READ missionTime NOTIFY missionTimeChanged)
Q_PROPERTY(double missionHoverDistance READ missionHoverDistance NOTIFY missionHoverDistanceChanged)
Q_PROPERTY(double missionCruiseDistance READ missionCruiseDistance NOTIFY missionCruiseDistanceChanged)
Q_PROPERTY(double missionHoverTime READ missionHoverTime NOTIFY missionHoverTimeChanged)
Q_PROPERTY(double missionCruiseTime READ missionCruiseTime NOTIFY missionCruiseTimeChanged)
Q_PROPERTY(double missionMaxTelemetry READ missionMaxTelemetry NOTIFY missionMaxTelemetryChanged)
Q_INVOKABLE void removeMissionItem(int index);
/// Add a new simple mission item to the list
/// @param i: index to insert at
/// @return Sequence number for new item
Q_INVOKABLE int insertSimpleMissionItem(QGeoCoordinate coordinate, int i);
/// Add a new complex mission item to the list
/// @param i: index to insert at
/// @return Sequence number for new item
Q_INVOKABLE int insertComplexMissionItem(QGeoCoordinate coordinate, int i);
// Overrides from PlanElementController
void start (bool editMode) final;
void startStaticActiveVehicle (Vehicle* vehicle) final;
void loadFromVehicle (void) final;
void sendToVehicle (void) final;
void loadFromFilePicker (void) final;
void loadFromFile (const QString& filename) final;
void saveToFilePicker (void) final;
void saveToFile (const QString& filename) final;
void removeAll (void) final;
bool syncInProgress (void) const final;
bool dirty (void) const final;
void setDirty (bool dirty) final;
QString fileExtension(void) const final;
// Property accessors
QGeoCoordinate plannedHomePosition (void);
QmlObjectListModel* visualItems (void) { return _visualItems; }
QmlObjectListModel* complexVisualItems (void) { return _complexItems; }
QmlObjectListModel* waypointLines (void) { return &_waypointLines; }
double missionDistance (void) const { return _missionDistance; }
double missionTime (void) const { return _missionTime; }
double missionHoverDistance (void) const { return _missionHoverDistance; }
double missionHoverTime (void) const { return _missionHoverTime; }
double missionCruiseDistance (void) const { return _missionCruiseDistance; }
double missionCruiseTime (void) const { return _missionCruiseTime; }
double missionMaxTelemetry (void) const { return _missionMaxTelemetry; }
double cruiseSpeed (void) const;
double hoverSpeed (void) const;
static void createVisualItemsFromFile(const QString& filename);
signals:
void plannedHomePositionChanged(QGeoCoordinate plannedHomePosition);
void visualItemsChanged(void);
void complexVisualItemsChanged(void);
void waypointLinesChanged(void);
void newItemsFromVehicle(void);
void missionDistanceChanged(double missionDistance);
void missionTimeChanged(void);
void missionHoverDistanceChanged(double missionHoverDistance);
void missionHoverTimeChanged(void);
void missionCruiseDistanceChanged(double missionCruiseDistance);
void missionCruiseTimeChanged(void);
void missionMaxTelemetryChanged(double missionMaxTelemetry);
void cruiseDistanceChanged(double cruiseDistance);
void hoverDistanceChanged(double hoverDistance);
void cruiseSpeedChanged(double cruiseSpeed);
void hoverSpeedChanged(double hoverSpeed);
private slots:
void _newMissionItemsAvailableFromVehicle();
void _itemCommandChanged(void);
void _activeVehicleHomePositionAvailableChanged(bool homePositionAvailable);
void _activeVehicleHomePositionChanged(const QGeoCoordinate& homePosition);
void _inProgressChanged(bool inProgress);
void _currentMissionItemChanged(int sequenceNumber);
void _recalcWaypointLines(void);
void _recalcAltitudeRangeBearing(void);
void _homeCoordinateChanged(void);
private:
void _init(void);
void _recalcSequence(void);
void _recalcChildItems(void);
void _recalcAll(void);
void _initAllVisualItems(void);
void _deinitAllVisualItems(void);
void _initVisualItem(VisualMissionItem* item);
void _deinitVisualItem(VisualMissionItem* item);
void _setupActiveVehicle(Vehicle* activeVehicle, bool forceLoadFromVehicle);
static void _calcPrevWaypointValues(double homeAlt, VisualMissionItem* currentItem, VisualMissionItem* prevItem, double* azimuth, double* distance, double* altDifference);
static double _calcDistanceToHome(VisualMissionItem* currentItem, VisualMissionItem* homeItem);
bool _findLastAltitude(double* lastAltitude, MAV_FRAME* frame);
bool _findLastAcceptanceRadius(double* lastAcceptanceRadius);
void _addPlannedHomePosition(QmlObjectListModel* visualItems, bool addToCenter);
double _normalizeLat(double lat);
double _normalizeLon(double lon);
bool _loadJsonMissionFile(const QByteArray& bytes, QmlObjectListModel* visualItems, QmlObjectListModel* complexItems, QString& errorString);
bool _loadJsonMissionFileV1(const QJsonObject& json, QmlObjectListModel* visualItems, QmlObjectListModel* complexItems, QString& errorString);
bool _loadJsonMissionFileV2(const QJsonObject& json, QmlObjectListModel* visualItems, QmlObjectListModel* complexItems, QString& errorString);
bool _loadTextMissionFile(QTextStream& stream, QmlObjectListModel* visualItems, QString& errorString);
int _nextSequenceNumber(void);
void _setMissionDistance(double missionDistance);
void _setMissionTime(double missionTime);
void _setMissionHoverDistance(double missionHoverDistance);
void _setMissionHoverTime(double missionHoverTime);
void _setMissionCruiseDistance(double missionCruiseDistance);
void _setMissionCruiseTime(double missionCruiseTime);
void _setMissionMaxTelemetry(double missionMaxTelemetry);
// Overrides from PlanElementController
void _activeVehicleBeingRemoved(void) final;
void _activeVehicleSet(void) final;
private:
QmlObjectListModel* _visualItems;
QmlObjectListModel* _complexItems;
QmlObjectListModel _waypointLines;
CoordVectHashTable _linesTable;
bool _firstItemsFromVehicle;
bool _missionItemsRequested;
bool _queuedSend;
double _missionDistance;
double _missionTime;
double _missionHoverDistance;
double _missionHoverTime;
double _missionCruiseDistance;
double _missionCruiseTime;
double _missionMaxTelemetry;
static const char* _settingsGroup;
static const char* _jsonFileTypeValue;
static const char* _jsonFirmwareTypeKey;
static const char* _jsonVehicleTypeKey;
static const char* _jsonCruiseSpeedKey;
static const char* _jsonHoverSpeedKey;
static const char* _jsonItemsKey;
static const char* _jsonPlannedHomePositionKey;
static const char* _jsonParamsKey;
// Deprecated V1 format keys
static const char* _jsonMavAutopilotKey;
static const char* _jsonComplexItemsKey;
static const int _missionFileVersion;
};
#endif
......@@ -21,8 +21,6 @@
QGC_LOGGING_CATEGORY(MissionSettingsComplexItemLog, "MissionSettingsComplexItemLog")
const char* MissionSettingsItem::jsonComplexItemTypeValue = "MissionSettings";
const char* MissionSettingsItem::_plannedHomePositionAltitudeName = "PlannedHomePositionAltitude";
QMap<QString, FactMetaData*> MissionSettingsItem::_metaDataMap;
......@@ -30,12 +28,8 @@ QMap<QString, FactMetaData*> MissionSettingsItem::_metaDataMap;
MissionSettingsItem::MissionSettingsItem(Vehicle* vehicle, bool flyView, QObject* parent)
: ComplexMissionItem (vehicle, flyView, parent)
, _plannedHomePositionAltitudeFact (0, _plannedHomePositionAltitudeName, FactMetaData::valueTypeDouble)
, _plannedHomePositionFromVehicle (false)
, _missionEndRTL (false)
, _cameraSection (vehicle)
, _speedSection (vehicle)
, _sequenceNumber (0)
, _dirty (false)
{
_editorQml = "qrc:/qml/MissionSettingsEditor.qml";
......@@ -51,20 +45,18 @@ MissionSettingsItem::MissionSettingsItem(Vehicle* vehicle, bool flyView, QObject
_speedSection.setAvailable(true);
connect(this, &MissionSettingsItem::specifyMissionFlightSpeedChanged, this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
connect(this, &MissionSettingsItem::missionEndRTLChanged, this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
connect(&_cameraSection, &CameraSection::itemCountChanged, this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
connect(&_speedSection, &CameraSection::itemCountChanged, this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
connect(this, &MissionSettingsItem::terrainAltitudeChanged, this, &MissionSettingsItem::_setHomeAltFromTerrain);
connect(&_cameraSection, &CameraSection::dirtyChanged, this, &MissionSettingsItem::_sectionDirtyChanged);
connect(&_speedSection, &SpeedSection::dirtyChanged, this, &MissionSettingsItem::_sectionDirtyChanged);
connect(&_cameraSection, &CameraSection::specifiedGimbalYawChanged, this, &MissionSettingsItem::specifiedGimbalYawChanged);
connect(&_cameraSection, &CameraSection::specifiedGimbalPitchChanged, this, &MissionSettingsItem::specifiedGimbalPitchChanged);
connect(&_speedSection, &SpeedSection::specifiedFlightSpeedChanged, this, &MissionSettingsItem::specifiedFlightSpeedChanged);
connect(_vehicle, &Vehicle::homePositionChanged, this, &MissionSettingsItem::_updateHomePosition);
connect(&_plannedHomePositionAltitudeFact, &Fact::rawValueChanged, this, &MissionSettingsItem::_updateAltitudeInCoordinate);
connect(&_cameraSection, &CameraSection::dirtyChanged, this, &MissionSettingsItem::_sectionDirtyChanged);
connect(&_speedSection, &SpeedSection::dirtyChanged, this, &MissionSettingsItem::_sectionDirtyChanged);
connect(&_cameraSection, &CameraSection::specifiedGimbalYawChanged, this, &MissionSettingsItem::specifiedGimbalYawChanged);
connect(&_cameraSection, &CameraSection::specifiedGimbalPitchChanged, this, &MissionSettingsItem::specifiedGimbalPitchChanged);
connect(&_speedSection, &SpeedSection::specifiedFlightSpeedChanged, this, &MissionSettingsItem::specifiedFlightSpeedChanged);
_updateHomePosition(_vehicle->homePosition());
}
int MissionSettingsItem::lastSequenceNumber(void) const
......@@ -95,7 +87,7 @@ void MissionSettingsItem::save(QJsonArray& missionItems)
appendMissionItems(items, this);
// First item show be planned home position, we are not responsible for save/load
// First item should be planned home position, we are not responsible for save/load
// Remaining items we just output as is
for (int i=1; i<items.count(); i++) {
MissionItem* item = items[i];
......@@ -161,26 +153,9 @@ void MissionSettingsItem::appendMissionItems(QList<MissionItem*>& items, QObject
_speedSection.appendSectionItems(items, missionItemParent, seqNum);
}
bool MissionSettingsItem::addMissionEndAction(QList<MissionItem*>& items, int seqNum, QObject* missionItemParent)
bool MissionSettingsItem::addMissionEndAction(QList<MissionItem*>& /*items*/, int /*seqNum*/, QObject* /*missionItemParent*/)
{
MissionItem* item = nullptr;
// IMPORTANT NOTE: If anything changes here you must also change MissionSettingsItem::scanForMissionSettings
if (_missionEndRTL) {
qCDebug(MissionSettingsComplexItemLog) << "Appending end action RTL seqNum" << seqNum;
item = new MissionItem(seqNum,
MAV_CMD_NAV_RETURN_TO_LAUNCH,
MAV_FRAME_MISSION,
0, 0, 0, 0, 0, 0, 0, // param 1-7 not used
true, // autoContinue
false, // isCurrentItem
missionItemParent);
items.append(item);
return true;
} else {
return false;
}
return false;
}
bool MissionSettingsItem::scanForMissionSettings(QmlObjectListModel* visualItems, int scanIndex)
......@@ -194,21 +169,6 @@ bool MissionSettingsItem::scanForMissionSettings(QmlObjectListModel* visualItems
foundCameraSection = _cameraSection.scanForSection(visualItems, scanIndex);
foundSpeedSection = _speedSection.scanForSection(visualItems, scanIndex);
// Look at the end of the mission for end actions
int lastIndex = visualItems->count() - 1;
SimpleMissionItem* item = visualItems->value<SimpleMissionItem*>(lastIndex);
if (item) {
MissionItem& missionItem = item->missionItem();
if (missionItem.command() == MAV_CMD_NAV_RETURN_TO_LAUNCH &&
missionItem.param1() == 0 && missionItem.param2() == 0 && missionItem.param3() == 0 && missionItem.param4() == 0 && missionItem.param5() == 0 && missionItem.param6() == 0 && missionItem.param7() == 0) {
qCDebug(MissionSettingsComplexItemLog) << "Scan: Found end action RTL";
_missionEndRTL = true;
visualItems->removeAt(lastIndex)->deleteLater();
}
}
return foundSpeedSection || foundCameraSection;
}
......@@ -222,25 +182,54 @@ void MissionSettingsItem::_setDirty(void)
setDirty(true);
}
void MissionSettingsItem::setHomePositionFromVehicle(const QGeoCoordinate& coordinate)
void MissionSettingsItem::_setCoordinateWorker(const QGeoCoordinate& coordinate)
{
_plannedHomePositionFromVehicle = true;
setCoordinate(coordinate);
if (_plannedHomePositionCoordinate != coordinate) {
_plannedHomePositionCoordinate = coordinate;
emit coordinateChanged(coordinate);
emit exitCoordinateChanged(coordinate);
_plannedHomePositionAltitudeFact.setRawValue(coordinate.altitude());
}
}
void MissionSettingsItem::setCoordinate(const QGeoCoordinate& coordinate)
void MissionSettingsItem::setHomePositionFromVehicle(Vehicle* vehicle)
{
if (_plannedHomePositionCoordinate != coordinate) {
// If the user hasn't moved the planned home position manually we use the value from the vehicle
if (!_plannedHomePositionMovedByUser) {
QGeoCoordinate coordinate = vehicle->homePosition();
// ArduPilot tends to send crap home positions at initial vehicle boot, discard them
if (coordinate.isValid() && (coordinate.latitude() != 0 || coordinate.longitude() != 0)) {
_plannedHomePositionCoordinate = coordinate;
emit coordinateChanged(coordinate);
emit exitCoordinateChanged(coordinate);
_plannedHomePositionAltitudeFact.setRawValue(coordinate.altitude());
_plannedHomePositionFromVehicle = true;
_setCoordinateWorker(coordinate);
}
}
}
void MissionSettingsItem::setInitialHomePosition(const QGeoCoordinate& coordinate)
{
_plannedHomePositionMovedByUser = false;
_plannedHomePositionFromVehicle = false;
_setCoordinateWorker(coordinate);
}
void MissionSettingsItem::setInitialHomePositionFromUser(const QGeoCoordinate& coordinate)
{
_plannedHomePositionMovedByUser = true;
_plannedHomePositionFromVehicle = false;
_setCoordinateWorker(coordinate);
}
void MissionSettingsItem::setCoordinate(const QGeoCoordinate& coordinate)
{
if (coordinate != this->coordinate()) {
// The user is moving the planned home position manually. Stop tracking vehicle home position.
_plannedHomePositionMovedByUser = true;
_plannedHomePositionFromVehicle = false;
_setCoordinateWorker(coordinate);
}
}
void MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber(void)
{
emit lastSequenceNumberChanged(lastSequenceNumber());
......@@ -284,14 +273,6 @@ double MissionSettingsItem::specifiedFlightSpeed(void)
}
}
void MissionSettingsItem::setMissionEndRTL(bool missionEndRTL)
{
if (missionEndRTL != _missionEndRTL) {
_missionEndRTL = missionEndRTL;
emit missionEndRTLChanged(missionEndRTL);
}
}
void MissionSettingsItem::_setHomeAltFromTerrain(double terrainAltitude)
{
if (!_plannedHomePositionFromVehicle && !qIsNaN(terrainAltitude)) {
......@@ -301,5 +282,12 @@ void MissionSettingsItem::_setHomeAltFromTerrain(double terrainAltitude)
QString MissionSettingsItem::abbreviation(void) const
{
return _flyView ? tr("H") : tr("Planned Home");
return _flyView ? tr("H") : tr("Launch");
}
void MissionSettingsItem::_updateHomePosition(const QGeoCoordinate& homePosition)
{
if (_flyView) {
setCoordinate(homePosition);
}
}
......@@ -27,17 +27,13 @@ public:
MissionSettingsItem(Vehicle* vehicle, bool flyView, QObject* parent);
Q_PROPERTY(Fact* plannedHomePositionAltitude READ plannedHomePositionAltitude CONSTANT)
Q_PROPERTY(bool missionEndRTL READ missionEndRTL WRITE setMissionEndRTL NOTIFY missionEndRTLChanged)
Q_PROPERTY(QObject* cameraSection READ cameraSection CONSTANT)
Q_PROPERTY(QObject* speedSection READ speedSection CONSTANT)
Fact* plannedHomePositionAltitude (void) { return &_plannedHomePositionAltitudeFact; }
bool missionEndRTL (void) const { return _missionEndRTL; }
CameraSection* cameraSection (void) { return &_cameraSection; }
SpeedSection* speedSection (void) { return &_speedSection; }
void setMissionEndRTL(bool missionEndRTL);
/// Scans the loaded items for settings items
bool scanForMissionSettings(QmlObjectListModel* visualItems, int scanIndex);
......@@ -48,8 +44,14 @@ public:
/// @return true: Mission end action was added
bool addMissionEndAction(QList<MissionItem*>& items, int seqNum, QObject* missionItemParent);
/// Called to updaet home position coordinate when it comes from a connected vehicle
void setHomePositionFromVehicle(const QGeoCoordinate& coordinate);
/// Called to update home position coordinate when it comes from a connected vehicle
void setHomePositionFromVehicle(Vehicle* vehicle);
// Called to set the initial home position. Vehicle can still update home position after this.
void setInitialHomePosition(const QGeoCoordinate& coordinate);
// Called to set the initial home position specified by user. Vehicle will no longer affect home position.
void setInitialHomePositionFromUser(const QGeoCoordinate& coordinate);
// Overrides from ComplexMissionItem
......@@ -75,7 +77,7 @@ public:
double specifiedGimbalYaw (void) final;
double specifiedGimbalPitch (void) final;
void appendMissionItems (QList<MissionItem*>& items, QObject* missionItemParent) final;
void applyNewAltitude (double newAltitude) final { Q_UNUSED(newAltitude); /* no action */ }
void applyNewAltitude (double /*newAltitude*/) final { /* no action */ }
double specifiedFlightSpeed (void) final;
double additionalTimeDelay (void) const final { return 0; }
......@@ -84,15 +86,12 @@ public:
bool exitCoordinateSameAsEntry (void) const final { return true; }
void setDirty (bool dirty) final;
void setCoordinate (const QGeoCoordinate& coordinate) final;
void setCoordinate (const QGeoCoordinate& coordinate) final; // Should only be called if the end user is moving
void setSequenceNumber (int sequenceNumber) final;
void save (QJsonArray& missionItems) final;
static const char* jsonComplexItemTypeValue;
signals:
void specifyMissionFlightSpeedChanged (bool specifyMissionFlightSpeed);
void missionEndRTLChanged (bool missionEndRTL);
private slots:
void _setDirtyAndUpdateLastSequenceNumber (void);
......@@ -100,16 +99,17 @@ private slots:
void _sectionDirtyChanged (bool dirty);
void _updateAltitudeInCoordinate (QVariant value);
void _setHomeAltFromTerrain (double terrainAltitude);
void _setCoordinateWorker (const QGeoCoordinate& coordinate);
void _updateHomePosition (const QGeoCoordinate& homePosition);
private:
QGeoCoordinate _plannedHomePositionCoordinate; // Does not include altitude
Fact _plannedHomePositionAltitudeFact;
bool _plannedHomePositionFromVehicle;
bool _missionEndRTL;
int _sequenceNumber = 0;
bool _plannedHomePositionFromVehicle = false;
bool _plannedHomePositionMovedByUser = false;
CameraSection _cameraSection;
SpeedSection _speedSection;
int _sequenceNumber;
bool _dirty;
static QMap<QString, FactMetaData*> _metaDataMap;
......
......@@ -19,7 +19,7 @@
#include "SurveyPlanCreator.h"
#include "StructureScanPlanCreator.h"
#include "CorridorScanPlanCreator.h"
#include "CustomPlanCreator.h"
#include "BlankPlanCreator.h"
#if defined(QGC_AIRMAP_ENABLED)
#include "AirspaceFlightPlanProvider.h"
#endif
......@@ -601,19 +601,19 @@ void PlanMasterController::_updatePlanCreatorsList(void)
if (!_flyView) {
if (!_planCreators) {
_planCreators = new QmlObjectListModel(this);
_planCreators->append(new BlankPlanCreator(this, this));
_planCreators->append(new SurveyPlanCreator(this, this));
_planCreators->append(new CorridorScanPlanCreator(this, this));
_planCreators->append(new CustomPlanCreator(this, this));
emit planCreatorsChanged(_planCreators);
}
if (_managerVehicle->fixedWing()) {
if (_planCreators->count() == 4) {
_planCreators->removeAt(_planCreators->count() - 2);
_planCreators->removeAt(_planCreators->count() - 1);
}
} else {
if (_planCreators->count() != 4) {
_planCreators->insert(_planCreators->count() - 1, new StructureScanPlanCreator(this, this));
_planCreators->append(new StructureScanPlanCreator(this, this));
}
}
}
......
......@@ -299,7 +299,8 @@ Item {
property int vertexIndex
sourceItem: SplitIndicator {
z: _zorderSplitHandle
z: _zorderSplitHandle
onClicked: mapPolygon.splitPolygonSegment(mapQuickItem.vertexIndex)
}
}
}
......@@ -538,7 +539,7 @@ Item {
QGCButton {
_horizontalPadding: 0
text: _traceMode ? qsTr("Done Tracing") : qsTr("Trace Polygon")
text: _traceMode ? qsTr("Done Tracing") : qsTr("Trace")
onClicked: {
if (_traceMode) {
if (mapPolygon.count < 3) {
......
......@@ -38,7 +38,7 @@ Item {
property real _zorderSplitHandle: QGroundControl.zOrderMapItems + 2
property var _savedVertices: [ ]
readonly property string _corridorToolsText: qsTr("Corridor Tools")
readonly property string _corridorToolsText: qsTr("Polyline Tools")
readonly property string _traceText: qsTr("Click in the map to add vertices. Click 'Done Tracing' when finished.")
function _addCommonVisuals() {
......
......@@ -146,37 +146,6 @@ SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, bool flyView, const Missi
setDirty(false);
}
SimpleMissionItem::SimpleMissionItem(const SimpleMissionItem& other, bool flyView, QObject* parent)
: VisualMissionItem (other, flyView, parent)
, _missionItem (other._vehicle)
, _rawEdit (false)
, _dirty (false)
, _ignoreDirtyChangeSignals (false)
, _speedSection (nullptr)
, _cameraSection (nullptr)
, _commandTree (qgcApp()->toolbox()->missionCommandTree())
, _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32)
, _altitudeMode (other._altitudeMode)
, _altitudeFact (0, "Altitude", FactMetaData::valueTypeDouble)
, _amslAltAboveTerrainFact (qQNaN(), "Alt above terrain", FactMetaData::valueTypeDouble)
, _param1MetaData (FactMetaData::valueTypeDouble)
, _param2MetaData (FactMetaData::valueTypeDouble)
, _param3MetaData (FactMetaData::valueTypeDouble)
, _param4MetaData (FactMetaData::valueTypeDouble)
, _syncingHeadingDegreesAndParam4 (false)
{
_editorQml = QStringLiteral("qrc:/qml/SimpleItemEditor.qml");
_altitudeFact.setRawValue(other._altitudeFact.rawValue());
_amslAltAboveTerrainFact.setRawValue(other._amslAltAboveTerrainFact.rawValue());
_setupMetaData();
_connectSignals();
_updateOptionalSections();
_rebuildFacts();
setDirty(false);
}
void SimpleMissionItem::_connectSignals(void)
{
// Connect to change signals to track dirty state
......@@ -430,6 +399,7 @@ QString SimpleMissionItem::abbreviation() const
case MAV_CMD_NAV_VTOL_LAND:
return tr("VTOL Land");
case MAV_CMD_DO_SET_ROI:
case MAV_CMD_DO_SET_ROI_LOCATION:
return tr("ROI");
default:
return QString();
......
......@@ -26,7 +26,7 @@ class SimpleMissionItem : public VisualMissionItem
public:
SimpleMissionItem(Vehicle* vehicle, bool flyView, QObject* parent);
SimpleMissionItem(Vehicle* vehicle, bool flyView, const MissionItem& missionItem, QObject* parent);
SimpleMissionItem(const SimpleMissionItem& other, bool flyView, QObject* parent);
//SimpleMissionItem(const SimpleMissionItem& other, bool flyView, QObject* parent);
~SimpleMissionItem();
......@@ -64,7 +64,8 @@ public:
// Property accesors
QString category (void) const;
int command(void) const { return _missionItem._commandFact.cookedValue().toInt(); }
int command (void) const { return _missionItem._commandFact.cookedValue().toInt(); }
MAV_CMD mavCommand (void) const { return static_cast<MAV_CMD>(command()); }
bool friendlyEditAllowed (void) const;
bool rawEdit (void) const;
bool specifiesAltitude (void) const;
......@@ -92,14 +93,14 @@ public:
void setAzimuth (double azimuth);
void setDistance (double distance);
bool load(QTextStream &loadStream);
bool load(const QJsonObject& json, int sequenceNumber, QString& errorString);
virtual bool load(QTextStream &loadStream);
virtual bool load(const QJsonObject& json, int sequenceNumber, QString& errorString);
MissionItem& missionItem(void) { return _missionItem; }
const MissionItem& missionItem(void) const { return _missionItem; }
// Overrides from VisualMissionItem
bool dirty (void) const final { return _dirty; }
bool dirty (void) const override { return _dirty; }
bool isSimpleItem (void) const final { return true; }
bool isStandaloneCoordinate (void) const final;
bool specifiesCoordinate (void) const final;
......@@ -110,10 +111,10 @@ public:
QGeoCoordinate coordinate (void) const final { return _missionItem.coordinate(); }
QGeoCoordinate exitCoordinate (void) const final { return coordinate(); }
int sequenceNumber (void) const final { return _missionItem.sequenceNumber(); }
double specifiedFlightSpeed (void) final;
double specifiedGimbalYaw (void) final;
double specifiedGimbalPitch (void) final;
QString mapVisualQML (void) const final { return QStringLiteral("SimpleItemMapVisual.qml"); }
double specifiedFlightSpeed (void) override;
double specifiedGimbalYaw (void) override;
double specifiedGimbalPitch (void) override;
QString mapVisualQML (void) const override { return QStringLiteral("SimpleItemMapVisual.qml"); }
void appendMissionItems (QList<MissionItem*>& items, QObject* missionItemParent) final;
void applyNewAltitude (double newAltitude) final;
void setMissionFlightStatus (MissionController::MissionFlightStatus_t& missionFlightStatus) final;
......@@ -125,7 +126,7 @@ public:
bool exitCoordinateSameAsEntry (void) const final { return true; }
void setDirty (bool dirty) final;
void setCoordinate (const QGeoCoordinate& coordinate) final;
void setCoordinate (const QGeoCoordinate& coordinate) override;
void setSequenceNumber (int sequenceNumber) final;
int lastSequenceNumber (void) const final;
void save (QJsonArray& missionItems) final;
......
......@@ -21,16 +21,8 @@ StructureScanPlanCreator::StructureScanPlanCreator(PlanMasterController* planMas
void StructureScanPlanCreator::createPlan(const QGeoCoordinate& mapCenterCoord)
{
_planMasterController->removeAll();
VisualMissionItem* takeoffItem = _missionController->insertSimpleMissionItem(mapCenterCoord, -1);
takeoffItem->setWizardMode(true);
VisualMissionItem* takeoffItem = _missionController->insertTakeoffItem(mapCenterCoord, -1);
_missionController->insertComplexMissionItem(MissionController::patternStructureScanName, mapCenterCoord, -1)->setWizardMode(true);
if (_planMasterController->managerVehicle()->fixedWing()) {
FixedWingLandingComplexItem* landingItem = qobject_cast<FixedWingLandingComplexItem*>(_missionController->insertComplexMissionItem(MissionController::patternFWLandingName, mapCenterCoord, -1));
landingItem->setWizardMode(true);
landingItem->setLoiterDragAngleOnly(true);
} else {
MissionSettingsItem* settingsItem = _missionController->visualItems()->value<MissionSettingsItem*>(0);
settingsItem->setMissionEndRTL(true);
}
_missionController->insertLandItem(mapCenterCoord, -1);
_missionController->setCurrentPlanViewIndex(takeoffItem->sequenceNumber(), true);
}
This diff is collapsed.
......@@ -22,16 +22,8 @@ SurveyPlanCreator::SurveyPlanCreator(PlanMasterController* planMasterController,
void SurveyPlanCreator::createPlan(const QGeoCoordinate& mapCenterCoord)
{
_planMasterController->removeAll();
VisualMissionItem* takeoffItem = _missionController->insertSimpleMissionItem(mapCenterCoord, -1);
takeoffItem->setWizardMode(true);
_missionController->insertComplexMissionItem(MissionController::patternSurveyName, mapCenterCoord, -1)->setWizardMode(true);
if (_planMasterController->managerVehicle()->fixedWing()) {
FixedWingLandingComplexItem* landingItem = qobject_cast<FixedWingLandingComplexItem*>(_missionController->insertComplexMissionItem(MissionController::patternFWLandingName, mapCenterCoord, -1));
landingItem->setWizardMode(true);
landingItem->setLoiterDragAngleOnly(true);
} else {
MissionSettingsItem* settingsItem = _missionController->visualItems()->value<MissionSettingsItem*>(0);
settingsItem->setMissionEndRTL(true);
}
VisualMissionItem* takeoffItem = _missionController->insertTakeoffItem(mapCenterCoord, -1);
_missionController->insertComplexMissionItem(MissionController::patternSurveyName, mapCenterCoord, -1);
_missionController->insertLandItem(mapCenterCoord, -1);
_missionController->setCurrentPlanViewIndex(takeoffItem->sequenceNumber(), true);
}
This diff is collapsed.
This diff is collapsed.
......@@ -16,6 +16,7 @@
#include "QGCApplication.h"
#include "JsonHelper.h"
#include "TerrainQuery.h"
#include "TakeoffMissionItem.h"
const char* VisualMissionItem::jsonTypeKey = "type";
const char* VisualMissionItem::jsonTypeSimpleItemValue = "SimpleItem";
......
......@@ -65,6 +65,7 @@ public:
Q_PROPERTY(bool isStandaloneCoordinate READ isStandaloneCoordinate NOTIFY isStandaloneCoordinateChanged) ///< true: Waypoint line does not go through item
Q_PROPERTY(bool specifiesAltitudeOnly READ specifiesAltitudeOnly NOTIFY specifiesAltitudeOnlyChanged) ///< true: Item has altitude only, no full coordinate
Q_PROPERTY(bool isSimpleItem READ isSimpleItem NOTIFY isSimpleItemChanged) ///< Simple or Complex MissionItem
Q_PROPERTY(bool isTakeoffItem READ isTakeoffItem NOTIFY isTakeoffItemChanged) ///< true: Takeoff item special case
Q_PROPERTY(QString editorQml MEMBER _editorQml CONSTANT) ///< Qml code for editing this item
Q_PROPERTY(QString mapVisualQML READ mapVisualQML CONSTANT) ///< QMl code for map visuals
Q_PROPERTY(QmlObjectListModel* childItems READ childItems CONSTANT)
......@@ -120,6 +121,7 @@ public:
virtual bool dirty (void) const = 0;
virtual bool isSimpleItem (void) const = 0;
virtual bool isTakeoffItem (void) const { return false; }
virtual bool isStandaloneCoordinate (void) const = 0;
virtual bool specifiesCoordinate (void) const = 0;
virtual bool specifiesAltitudeOnly (void) const = 0;
......@@ -194,6 +196,7 @@ signals:
void isCurrentItemChanged (bool isCurrentItem);
void sequenceNumberChanged (int sequenceNumber);
void isSimpleItemChanged (bool isSimpleItem);
void isTakeoffItemChanged (bool isTakeoffItem);
void specifiesCoordinateChanged (void);
void isStandaloneCoordinateChanged (void);
void specifiesAltitudeOnlyChanged (void);
......
......@@ -14,7 +14,6 @@ add_custom_target(PlanViewQml
MissionItemStatus.qml
MissionSettingsEditor.qml
PlanEditToolbar.qml
PlanStartOverlay.qml
PlanToolBarIndicators.qml
PlanToolBar.qml
PlanView.qml
......
......@@ -24,6 +24,8 @@ Column {
SectionHeader {
id: cameraSectionHeader
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Camera")
checked: false
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -24,6 +24,7 @@ QGC_LOGGING_CATEGORY(ParameterManagerLog, "ParameterManagerLog")
QGC_LOGGING_CATEGORY(GeotaggingLog, "GeotaggingLog")
QGC_LOGGING_CATEGORY(RTKGPSLog, "RTKGPSLog")
QGC_LOGGING_CATEGORY(GuidedActionsControllerLog, "GuidedActionsControllerLog")
QGC_LOGGING_CATEGORY(ADSBVehicleManagerLog, "ADSBVehicleManagerLog")
QGCLoggingCategoryRegister* _instance = nullptr;
const char* QGCLoggingCategoryRegister::_filterRulesSettingsGroup = "LoggingFilters";
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment