Browse Source

Merge branch 'master' of https://github.com/mavlink/qgroundcontrol

* 'master' of https://github.com/mavlink/qgroundcontrol: (37 commits)
  Update ISSUE_TEMPLATE.md
  Update ISSUE_TEMPLATE.md
  Create ISSUE_TEMPLATE.md
  Revert "Remove FileManager unit test"
  Revert "Temp removal of Onboard File"
  FileManager: fix upload complete
  QGCUASFileView.cc: fix upload complete
  Flight display: Fixed TypeErrors on startup without gstream installed
  Fix timeout logic
  10 sec timeout on vehicle
  Stack callsign below altitude
  Flight display: Create property variable
  Flight display: Remove video record button when gstreamer is not installed
  Add missing lib
  Flight display: Add callsign to transponders
  Add missing lib
  Better display of vehicle indicators for multi-vehicle
  Add support for ADSB vehicle display
  travis-ci fix indentation
  travis-ci fix google play deploy and quiet wget
  ...
QGC4.4
Gus Grubba 8 years ago
parent
commit
2396eb6e5e
  1. 33
      .travis.yml
  2. 4
      ISSUE_TEMPLATE.md
  3. 2
      QGCInstaller.pri
  4. 2
      QGCSetup.pri
  5. 6
      deploy/qgroundcontrol_installer.nsi
  6. 2
      ios/iOSForAppStore-Info-Source.plist
  7. 1
      qgcresources.qrc
  8. 8
      qgroundcontrol.pro
  9. 2
      src/FirmwarePlugin/APM/ArduCopterFirmwarePlugin.h
  10. 13
      src/FlightDisplay/FlightDisplayView.qml
  11. 18
      src/FlightDisplay/FlightDisplayViewMap.qml
  12. 16
      src/FlightDisplay/FlightDisplayViewVideo.qml
  13. 41
      src/FlightDisplay/GuidedActionsController.qml
  14. 135
      src/FlightDisplay/MultiVehicleList.qml
  15. 66
      src/FlightMap/Images/adsbVehicle.svg
  16. 69
      src/FlightMap/MapItems/VehicleMapItem.qml
  17. 2
      src/MissionManager/GeoFenceController.cc
  18. 5
      src/MissionManager/MissionController.cc
  19. 4
      src/MissionManager/Survey.SettingsGroup.json
  20. 2
      src/PlanView/PlanView.qml
  21. 71
      src/Vehicle/ADSBVehicle.cc
  22. 51
      src/Vehicle/ADSBVehicle.h
  23. 86
      src/Vehicle/Vehicle.cc
  24. 8
      src/Vehicle/Vehicle.h
  25. 39
      src/VehicleSetup/FirmwareUpgradeController.cc
  26. 16
      src/api/QGCCorePlugin.cc
  27. 7
      src/api/QGCCorePlugin.h
  28. 35
      src/comm/MockLink.cc
  29. 10
      src/comm/MockLink.h
  30. 4
      src/qgcunittest/UnitTestList.cc
  31. 1
      src/uas/FileManager.cc
  32. 11
      src/ui/MainWindow.cc
  33. 2
      src/ui/QGCUASFileView.cc

33
.travis.yml

@ -72,7 +72,7 @@ before_install:
# install ccache for osx/ios # install ccache for osx/ios
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
wget https://s3.amazonaws.com/px4-travis/toolchain/macos/ccache && wget --quiet https://s3.amazonaws.com/px4-travis/toolchain/macos/ccache &&
chmod +x ccache && sudo mv ccache /usr/local/bin; chmod +x ccache && sudo mv ccache /usr/local/bin;
fi fi
@ -89,7 +89,7 @@ before_install:
install: install:
# linux dependencies: qt # linux dependencies: qt
- if [ "${SPEC}" = "linux-g++-64" ]; then - if [ "${SPEC}" = "linux-g++-64" ]; then
wget https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.7.1-linux-min.tar.bz2 && wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.7.1-linux-min.tar.bz2 &&
tar jxf Qt5.7.1-linux-min.tar.bz2 -C /tmp && tar jxf Qt5.7.1-linux-min.tar.bz2 -C /tmp &&
export PATH=/tmp/Qt5.7-linux/5.7/gcc_64/bin:$PATH && export PATH=/tmp/Qt5.7-linux/5.7/gcc_64/bin:$PATH &&
export DISPLAY=:99.0 && export DISPLAY=:99.0 &&
@ -99,12 +99,12 @@ install:
# android dependencies: qt, gstreamer, android-ndk # android dependencies: qt, gstreamer, android-ndk
- if [ "${SPEC}" = "android-g++" ]; then - if [ "${SPEC}" = "android-g++" ]; then
wget https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.7.1-android-min.tar.bz2 && wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.7.1-android-min.tar.bz2 &&
tar jxf Qt5.7.1-android-min.tar.bz2 -C /tmp && tar jxf Qt5.7.1-android-min.tar.bz2 -C /tmp &&
wget https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/gstreamer-1.0-android-armv7-1.5.2.tar.bz2 && wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/gstreamer-1.0-android-armv7-1.5.2.tar.bz2 &&
mkdir -p ${TRAVIS_BUILD_DIR}/gstreamer-1.0-android-armv7-1.5.2 && mkdir -p ${TRAVIS_BUILD_DIR}/gstreamer-1.0-android-armv7-1.5.2 &&
tar jxf gstreamer-1.0-android-armv7-1.5.2.tar.bz2 -C ${TRAVIS_BUILD_DIR}/gstreamer-1.0-android-armv7-1.5.2 && tar jxf gstreamer-1.0-android-armv7-1.5.2.tar.bz2 -C ${TRAVIS_BUILD_DIR}/gstreamer-1.0-android-armv7-1.5.2 &&
wget http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin && wget --quiet http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin &&
chmod +x android-ndk-r10e-linux-x86_64.bin && chmod +x android-ndk-r10e-linux-x86_64.bin &&
./android-ndk-r10e-linux-x86_64.bin > /dev/null && ./android-ndk-r10e-linux-x86_64.bin > /dev/null &&
export ANDROID_NDK_ROOT=`pwd`/android-ndk-r10e && export ANDROID_NDK_ROOT=`pwd`/android-ndk-r10e &&
@ -115,13 +115,13 @@ install:
# osx dependencies: qt, gstreamer, gstreamer-devel # osx dependencies: qt, gstreamer, gstreamer-devel
- if [ "${SPEC}" = "macx-clang" ]; then - if [ "${SPEC}" = "macx-clang" ]; then
wget https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.7.1-mac-clang-min.tar.bz2 && wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.7.1-mac-clang-min.tar.bz2 &&
tar jxf Qt5.7.1-mac-clang-min.tar.bz2 -C /tmp && tar jxf Qt5.7.1-mac-clang-min.tar.bz2 -C /tmp &&
wget https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/gstreamer-1.0-1.5.2-x86_64.pkg && wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/gstreamer-1.0-1.5.2-x86_64.pkg &&
sudo installer -verboseR -pkg gstreamer-1.0-1.5.2-x86_64.pkg -target / && sudo installer -verboseR -pkg gstreamer-1.0-1.5.2-x86_64.pkg -target / &&
wget https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/gstreamer-1.0-devel-1.5.2-x86_64.pkg && wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/gstreamer-1.0-devel-1.5.2-x86_64.pkg &&
sudo installer -verboseR -pkg gstreamer-1.0-devel-1.5.2-x86_64.pkg -target / && sudo installer -verboseR -pkg gstreamer-1.0-devel-1.5.2-x86_64.pkg -target / &&
wget https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/osx-gstreamer.tar.bz2 && wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/osx-gstreamer.tar.bz2 &&
sudo tar jxf osx-gstreamer.tar.bz2 -C /Library/Frameworks && sudo tar jxf osx-gstreamer.tar.bz2 -C /Library/Frameworks &&
export QT_DIR=Qt5.7-mac-clang/5.7/clang_64 && export QT_DIR=Qt5.7-mac-clang/5.7/clang_64 &&
export QT_QPA_PLATFORM_PLUGIN_PATH=/tmp/$QT_DIR/plugins && export QT_QPA_PLATFORM_PLUGIN_PATH=/tmp/$QT_DIR/plugins &&
@ -132,7 +132,7 @@ install:
# ios dependencies: qt, TODO: add gstreamer # ios dependencies: qt, TODO: add gstreamer
- if [ "${SPEC}" = "macx-ios-clang" ]; then - if [ "${SPEC}" = "macx-ios-clang" ]; then
wget https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.8.0-ios-min.tar.bz2 && wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.8.0-ios-min.tar.bz2 &&
tar jxf Qt5.8.0-ios-min.tar.bz2 -C /tmp && tar jxf Qt5.8.0-ios-min.tar.bz2 -C /tmp &&
export IOS_CCACHE_CC=`/usr/bin/xcrun -sdk iphoneos -find clang` && export IOS_CCACHE_CC=`/usr/bin/xcrun -sdk iphoneos -find clang` &&
export IOS_CCACHE_CXX=`/usr/bin/xcrun -sdk iphoneos -find clang++` && export IOS_CCACHE_CXX=`/usr/bin/xcrun -sdk iphoneos -find clang++` &&
@ -145,8 +145,8 @@ before_script:
- cd ${TRAVIS_BUILD_DIR} - cd ${TRAVIS_BUILD_DIR}
# grab latest PX4 parameter and airframe metadata # grab latest PX4 parameter and airframe metadata
- wget http://px4-travis.s3.amazonaws.com/Firmware/master/parameters.xml -O src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml - wget --quiet http://px4-travis.s3.amazonaws.com/Firmware/master/parameters.xml -O src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml
- wget http://px4-travis.s3.amazonaws.com/Firmware/master/airframes.xml -O src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml - wget --quiet http://px4-travis.s3.amazonaws.com/Firmware/master/airframes.xml -O src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml
# switch android config from installer to release if the android storepass isn't available # switch android config from installer to release if the android storepass isn't available
- if [[ "${SPEC}" = "android-g++" && "${CONFIG}" = "installer" && -z ${ANDROID_STOREPASS} ]]; then - if [[ "${SPEC}" = "android-g++" && "${CONFIG}" = "installer" && -z ${ANDROID_STOREPASS} ]]; then
@ -156,7 +156,7 @@ before_script:
# insert QGC version in AndroidManifest.xml # insert QGC version in AndroidManifest.xml
- if [ "${SPEC}" = "android-g++" ]; then - if [ "${SPEC}" = "android-g++" ]; then
git remote set-branches origin 'master' && git remote set-branches origin 'master' &&
git fetch origin master && git fetch --tags origin master &&
./tools/update_android_version.sh; ./tools/update_android_version.sh;
fi fi
@ -183,12 +183,15 @@ after_success:
- cd ${TRAVIS_BUILD_DIR} - cd ${TRAVIS_BUILD_DIR}
# master development builds to beta track # master development builds to beta track
# tagged releases first to beta track then manually move to production
- GOOGLE_PLAY_PKG=org.mavlink.qgroundcontrolbeta - GOOGLE_PLAY_PKG=org.mavlink.qgroundcontrolbeta
- if [ "${TRAVIS_TAG}" ]; then - if [ "${TRAVIS_TAG}" ]; then
GOOGLE_PLAY_PKG=org.mavlink.qgroundcontrol; GOOGLE_PLAY_PKG=org.mavlink.qgroundcontrol;
elif [ "${TRAVIS_BRANCH}" = "master" ]; then
GOOGLE_PLAY_PKG=org.mavlink.qgroundcontrolbeta;
else
GOOGLE_PLAY_PKG=none;
fi fi
- if [[ "${SPEC}" = "android-g++" && "${TRAVIS_PULL_REQUEST}" = "false" && "${TRAVIS_BRANCH}" = "master" ]]; then - if [[ "${SPEC}" = "android-g++" && "${TRAVIS_PULL_REQUEST}" = "false" && "${GOOGLE_PLAY_PKG}" != "none" ]]; then
pip install --user google-api-python-client PyOpenSSL && pip install --user google-api-python-client PyOpenSSL &&
openssl aes-256-cbc -K $encrypted_25db6eb7c3fd_key -iv $encrypted_25db6eb7c3fd_iv -in android/Google_Play_Android_Developer-4432a3c4f5d1.json.enc -out android/Google_Play_Android_Developer-4432a3c4f5d1.json -d && openssl aes-256-cbc -K $encrypted_25db6eb7c3fd_key -iv $encrypted_25db6eb7c3fd_iv -in android/Google_Play_Android_Developer-4432a3c4f5d1.json.enc -out android/Google_Play_Android_Developer-4432a3c4f5d1.json -d &&
./tools/google_play_upload.py production ${GOOGLE_PLAY_PKG} ${SHADOW_BUILD_DIR}/release/package/QGroundControl.apk; ./tools/google_play_upload.py production ${GOOGLE_PLAY_PKG} ${SHADOW_BUILD_DIR}/release/package/QGroundControl.apk;

4
ISSUE_TEMPLATE.md

@ -0,0 +1,4 @@
Note: GitHub Issues are for bugs or feature requests only. Do not enter Issues for questions regarding usage or problems building QGC yourself.
Use the appropriate support channel instead: http://qgroundcontrol.com/#resources.
Delete all of this text when create a real bug Issue.

2
QGCInstaller.pri

@ -35,7 +35,7 @@ installer {
QMAKE_POST_LINK += && hdiutil create -verbose -stretch 4g -layout SPUD -srcfolder $${DESTDIR}/$${TARGET}.app -volname $${TARGET} $${DESTDIR}/package/$${TARGET}.dmg QMAKE_POST_LINK += && hdiutil create -verbose -stretch 4g -layout SPUD -srcfolder $${DESTDIR}/$${TARGET}.app -volname $${TARGET} $${DESTDIR}/package/$${TARGET}.dmg
} }
WindowsBuild { WindowsBuild {
QMAKE_POST_LINK += $$escape_expand(\\n) cd $$BASEDIR_WIN && $$quote("\"C:\\Program Files \(x86\)\\NSIS\\makensis.exe\"" /DAPPNAME="\"$${QGC_APP_NAME}\"" /DEXENAME="\"$${TARGET}\"" /DORGNAME="\"$${QGC_ORG_NAME}\"" /DDESTDIR=$${DESTDIR} /NOCD "\"/XOutFile $${DESTDIR_WIN}\\$${TARGET}-installer.exe\"" "$$BASEDIR_WIN\\deploy\\qgroundcontrol_installer.nsi") QMAKE_POST_LINK += $$escape_expand(\\n) cd $$BASEDIR_WIN && $$quote("\"C:\\Program Files \(x86\)\\NSIS\\makensis.exe\"" /DINSTALLER_ICON="\"$${QGC_INSTALLER_ICON}\"" /DHEADER_BITMAP="\"$${QGC_INSTALLER_HEADER_BITMAP}\"" /DAPPNAME="\"$${QGC_APP_NAME}\"" /DEXENAME="\"$${TARGET}\"" /DORGNAME="\"$${QGC_ORG_NAME}\"" /DDESTDIR=$${DESTDIR} /NOCD "\"/XOutFile $${DESTDIR_WIN}\\$${TARGET}-installer.exe\"" "$$BASEDIR_WIN\\deploy\\qgroundcontrol_installer.nsi")
OTHER_FILES += deploy/qgroundcontrol_installer.nsi OTHER_FILES += deploy/qgroundcontrol_installer.nsi
} }
LinuxBuild { LinuxBuild {

2
QGCSetup.pri

@ -114,6 +114,8 @@ LinuxBuild {
libQt5PrintSupport.so.5 \ libQt5PrintSupport.so.5 \
libQt5Qml.so.5 \ libQt5Qml.so.5 \
libQt5Quick.so.5 \ libQt5Quick.so.5 \
libQt5QuickControls2.so.5 \
libQt5QuickTemplates2.so.5 \
libQt5QuickWidgets.so.5 \ libQt5QuickWidgets.so.5 \
libQt5SerialPort.so.5 \ libQt5SerialPort.so.5 \
libQt5Sql.so.5 \ libQt5Sql.so.5 \

6
deploy/qgroundcontrol_installer.nsi

@ -44,9 +44,9 @@ InstallDir "$PROGRAMFILES\${APPNAME}"
SetCompressor /SOLID /FINAL lzma SetCompressor /SOLID /FINAL lzma
!define MUI_HEADERIMAGE !define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "installheader.bmp"; !define MUI_HEADERIMAGE_BITMAP "${HEADER_BITMAP}";
!define MUI_ICON "WindowsQGC.ico"; !define MUI_ICON "${INSTALLER_ICON}";
!define MUI_UNICON "WindowsQGC.ico"; !define MUI_UNICON "${INSTALLER_ICON}";
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder !insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder
!insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_DIRECTORY

2
ios/iOSForAppStore-Info-Source.plist

@ -85,6 +85,8 @@
<string>Ground Station Location</string> <string>Ground Station Location</string>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
<string>QGCLaunchScreen</string> <string>QGCLaunchScreen</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>QGroundControl would like to use bluetooth.</string>
<key>UIRequiresFullScreen</key> <key>UIRequiresFullScreen</key>
<true/> <true/>
<key>UISupportedInterfaceOrientations</key> <key>UISupportedInterfaceOrientations</key>

1
qgcresources.qrc

@ -113,6 +113,7 @@
<file alias="scale_end.png">src/FlightMap/Images/scale_end.png</file> <file alias="scale_end.png">src/FlightMap/Images/scale_end.png</file>
<file alias="scaleLight.png">src/FlightMap/Images/scaleLight.png</file> <file alias="scaleLight.png">src/FlightMap/Images/scaleLight.png</file>
<file alias="scale_endLight.png">src/FlightMap/Images/scale_endLight.png</file> <file alias="scale_endLight.png">src/FlightMap/Images/scale_endLight.png</file>
<file alias="adsbVehicle.svg">src/FlightMap/Images/adsbVehicle.svg</file>
<file alias="vehicleArrowOutline.svg">src/FlightMap/Images/vehicleArrowOutline.svg</file> <file alias="vehicleArrowOutline.svg">src/FlightMap/Images/vehicleArrowOutline.svg</file>
<file alias="vehicleArrowOpaque.svg">src/FlightMap/Images/vehicleArrowOpaque.svg</file> <file alias="vehicleArrowOpaque.svg">src/FlightMap/Images/vehicleArrowOpaque.svg</file>
<file alias="ZoomPlus.svg">src/FlightMap/Images/ZoomPlus.svg</file> <file alias="ZoomPlus.svg">src/FlightMap/Images/ZoomPlus.svg</file>

8
qgroundcontrol.pro

@ -55,6 +55,8 @@ iOSBuild {
count(APP_ERROR, 1) { count(APP_ERROR, 1) {
error("Error building .plist file. 'ForAppStore' builds are only possible through the official build system.") error("Error building .plist file. 'ForAppStore' builds are only possible through the official build system.")
} }
QT += qml-private
CONFIG += qtquickcompiler
QMAKE_INFO_PLIST = $${BASEDIR}/ios/iOSForAppStore-Info.plist QMAKE_INFO_PLIST = $${BASEDIR}/ios/iOSForAppStore-Info.plist
OTHER_FILES += $${BASEDIR}/ios/iOSForAppStore-Info.plist OTHER_FILES += $${BASEDIR}/ios/iOSForAppStore-Info.plist
} else { } else {
@ -82,6 +84,10 @@ QGC_ORG_DOMAIN = "org.qgroundcontrol"
QGC_APP_DESCRIPTION = "Open source ground control app provided by QGroundControl dev team" QGC_APP_DESCRIPTION = "Open source ground control app provided by QGroundControl dev team"
QGC_APP_COPYRIGHT = "Copyright (C) 2017 QGroundControl Development Team. All rights reserved." QGC_APP_COPYRIGHT = "Copyright (C) 2017 QGroundControl Development Team. All rights reserved."
WindowsBuild {
QGC_INSTALLER_ICON = "WindowsQGC.ico"
QGC_INSTALLER_HEADER_BITMAP = "installheader.bmp"
}
# Load additional config flags from user_config.pri # Load additional config flags from user_config.pri
exists(user_config.pri):infile(user_config.pri, CONFIG) { exists(user_config.pri):infile(user_config.pri, CONFIG) {
@ -830,6 +836,7 @@ HEADERS+= \
src/FirmwarePlugin/CameraMetaData.h \ src/FirmwarePlugin/CameraMetaData.h \
src/FirmwarePlugin/FirmwarePlugin.h \ src/FirmwarePlugin/FirmwarePlugin.h \
src/FirmwarePlugin/FirmwarePluginManager.h \ src/FirmwarePlugin/FirmwarePluginManager.h \
src/Vehicle/ADSBVehicle.h \
src/Vehicle/MultiVehicleManager.h \ src/Vehicle/MultiVehicleManager.h \
src/Vehicle/GPSRTKFactGroup.h \ src/Vehicle/GPSRTKFactGroup.h \
src/Vehicle/Vehicle.h \ src/Vehicle/Vehicle.h \
@ -855,6 +862,7 @@ SOURCES += \
src/FirmwarePlugin/CameraMetaData.cc \ src/FirmwarePlugin/CameraMetaData.cc \
src/FirmwarePlugin/FirmwarePlugin.cc \ src/FirmwarePlugin/FirmwarePlugin.cc \
src/FirmwarePlugin/FirmwarePluginManager.cc \ src/FirmwarePlugin/FirmwarePluginManager.cc \
src/Vehicle/ADSBVehicle.cc \
src/Vehicle/MultiVehicleManager.cc \ src/Vehicle/MultiVehicleManager.cc \
src/Vehicle/GPSRTKFactGroup.cc \ src/Vehicle/GPSRTKFactGroup.cc \
src/Vehicle/Vehicle.cc \ src/Vehicle/Vehicle.cc \

2
src/FirmwarePlugin/APM/ArduCopterFirmwarePlugin.h

@ -73,7 +73,7 @@ public:
QString missionFlightMode (void) const override { return QString("Auto"); } QString missionFlightMode (void) const override { return QString("Auto"); }
QString rtlFlightMode (void) const override { return QString("RTL"); } QString rtlFlightMode (void) const override { return QString("RTL"); }
QString landFlightMode (void) const override { return QString("Land"); } QString landFlightMode (void) const override { return QString("Land"); }
QString takeControlFlightMode (void) const override { return QString("Stablize"); } QString takeControlFlightMode (void) const override { return QString("Loiter"); }
bool vehicleYawsToNextWaypointInMission (const Vehicle* vehicle) const final; bool vehicleYawsToNextWaypointInMission (const Vehicle* vehicle) const final;
QString autoDisarmParameter (Vehicle* vehicle) final { Q_UNUSED(vehicle); return QStringLiteral("DISARM_DELAY"); } QString autoDisarmParameter (Vehicle* vehicle) final { Q_UNUSED(vehicle); return QStringLiteral("DISARM_DELAY"); }
void startMission (Vehicle* vehicle) override; void startMission (Vehicle* vehicle) override;

13
src/FlightDisplay/FlightDisplayView.qml

@ -43,6 +43,7 @@ QGCView {
property var _geoFenceController: _planMasterController.geoFenceController property var _geoFenceController: _planMasterController.geoFenceController
property var _rallyPointController: _planMasterController.rallyPointController property var _rallyPointController: _planMasterController.rallyPointController
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property var _videoReceiver: QGroundControl.videoManager.videoReceiver
property bool _mainIsMap: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_mainIsMapKey, true) : true property bool _mainIsMap: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_mainIsMapKey, true) : true
property bool _isPipVisible: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_PIPVisibleKey, true) : false property bool _isPipVisible: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_PIPVisibleKey, true) : false
property real _savedZoomLevel: 0 property real _savedZoomLevel: 0
@ -331,7 +332,7 @@ QGCView {
QGCRadioButton { QGCRadioButton {
exclusiveGroup: multiVehicleSelectorGroup exclusiveGroup: multiVehicleSelectorGroup
text: qsTr("Multi-Vehicle (WIP)") text: qsTr("Multi-Vehicle")
color: mapPal.text color: mapPal.text
} }
} }
@ -339,7 +340,7 @@ QGCView {
FlightDisplayViewWidgets { FlightDisplayViewWidgets {
id: flightDisplayViewWidgets id: flightDisplayViewWidgets
z: _panel.z + 4 z: _panel.z + 4
height: ScreenTools.availableHeight height: ScreenTools.availableHeight - (singleMultiSelector.visible ? singleMultiSelector.height + _margins : 0)
anchors.left: parent.left anchors.left: parent.left
anchors.right: altitudeSlider.visible ? altitudeSlider.left : parent.right anchors.right: altitudeSlider.visible ? altitudeSlider.left : parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@ -370,14 +371,14 @@ QGCView {
anchors.right: _flightVideo.right anchors.right: _flightVideo.right
height: ScreenTools.defaultFontPixelHeight * 2 height: ScreenTools.defaultFontPixelHeight * 2
width: height width: height
visible: QGroundControl.videoManager.videoReceiver.videoRunning && QGroundControl.settingsManager.videoSettings.showRecControl.rawValue visible: _videoReceiver && _videoReceiver.videoRunning && QGroundControl.settingsManager.videoSettings.showRecControl.rawValue
opacity: 0.75 opacity: 0.75
Rectangle { Rectangle {
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
width: height width: height
radius: QGroundControl.videoManager && QGroundControl.videoManager.videoReceiver && QGroundControl.videoManager.videoReceiver.recording ? 0 : height radius: QGroundControl.videoManager && _videoReceiver && _videoReceiver.recording ? 0 : height
color: "red" color: "red"
} }
@ -394,7 +395,7 @@ QGCView {
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: QGroundControl.videoManager.videoReceiver && QGroundControl.videoManager.videoReceiver.recording ? QGroundControl.videoManager.videoReceiver.stopRecording() : QGroundControl.videoManager.videoReceiver.startRecording() onClicked: _videoReceiver && _videoReceiver.recording ? _videoReceiver.stopRecording() : _videoReceiver.startRecording()
} }
} }
@ -406,9 +407,9 @@ QGCView {
width: ScreenTools.defaultFontPixelWidth * 30 width: ScreenTools.defaultFontPixelWidth * 30
visible: !singleVehicleView.checked visible: !singleVehicleView.checked
z: _panel.z + 4 z: _panel.z + 4
guidedActionsController: _guidedController
} }
//-- Virtual Joystick //-- Virtual Joystick
Loader { Loader {
id: virtualJoystickMultiTouch id: virtualJoystickMultiTouch

18
src/FlightDisplay/FlightDisplayViewMap.qml

@ -184,12 +184,28 @@ FlightMap {
delegate: VehicleMapItem { delegate: VehicleMapItem {
vehicle: object vehicle: object
coordinate: object.coordinate coordinate: object.coordinate
isSatellite: flightMap.isSatelliteMap map: flightMap
size: _mainIsMap ? ScreenTools.defaultFontPixelHeight * 3 : ScreenTools.defaultFontPixelHeight size: _mainIsMap ? ScreenTools.defaultFontPixelHeight * 3 : ScreenTools.defaultFontPixelHeight
z: QGroundControl.zOrderVehicles z: QGroundControl.zOrderVehicles
} }
} }
// Add ADSB vehicles to the map
MapItemView {
model: _activeVehicle ? _activeVehicle.adsbVehicles : 0
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
delegate: VehicleMapItem {
coordinate: object.coordinate
altitude: object.altitude
callsign: object.callsign
heading: object.heading
map: flightMap
z: QGroundControl.zOrderVehicles
}
}
// Add the mission item visuals to the map // Add the mission item visuals to the map
Repeater { Repeater {
model: _mainIsMap ? _missionController.visualItems : 0 model: _mainIsMap ? _missionController.visualItems : 0

16
src/FlightDisplay/FlightDisplayViewVideo.qml

@ -25,11 +25,13 @@ Item {
id: root id: root
property double _ar: QGroundControl.settingsManager.videoSettings.aspectRatio.rawValue property double _ar: QGroundControl.settingsManager.videoSettings.aspectRatio.rawValue
property bool _showGrid: QGroundControl.settingsManager.videoSettings.gridLines.rawValue > 0 property bool _showGrid: QGroundControl.settingsManager.videoSettings.gridLines.rawValue > 0
property var _videoReceiver: QGroundControl.videoManager.videoReceiver
Rectangle { Rectangle {
id: noVideo id: noVideo
anchors.fill: parent anchors.fill: parent
color: Qt.rgba(0,0,0,0.75) color: Qt.rgba(0,0,0,0.75)
visible: !QGroundControl.videoManager.videoReceiver.videoRunning visible: !(_videoReceiver && _videoReceiver.videoRunning)
QGCLabel { QGCLabel {
text: qsTr("WAITING FOR VIDEO") text: qsTr("WAITING FOR VIDEO")
font.family: ScreenTools.demiboldFontFamily font.family: ScreenTools.demiboldFontFamily
@ -41,20 +43,20 @@ Item {
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
color: "black" color: "black"
visible: QGroundControl.videoManager.videoReceiver.videoRunning visible: _videoReceiver && _videoReceiver.videoRunning
QGCVideoBackground { QGCVideoBackground {
id: videoContent id: videoContent
height: parent.height height: parent.height
width: _ar != 0.0 ? height * _ar : parent.width width: _ar != 0.0 ? height * _ar : parent.width
anchors.centerIn: parent anchors.centerIn: parent
receiver: QGroundControl.videoManager.videoReceiver receiver: _videoReceiver
display: QGroundControl.videoManager.videoReceiver.videoSurface display: _videoReceiver && _videoReceiver.videoSurface
visible: QGroundControl.videoManager.videoReceiver.videoRunning visible: _videoReceiver && _videoReceiver.videoRunning
Connections { Connections {
target: QGroundControl.videoManager.videoReceiver target: _videoReceiver
onImageFileChanged: { onImageFileChanged: {
videoContent.grabToImage(function(result) { videoContent.grabToImage(function(result) {
if (!result.saveToFile(QGroundControl.videoManager.videoReceiver.imageFile)) { if (!result.saveToFile(_videoReceiver.imageFile)) {
console.error('Error capturing video frame'); console.error('Error capturing video frame');
} }
}); });

41
src/FlightDisplay/GuidedActionsController.qml

@ -64,6 +64,7 @@ Item {
readonly property string orbitMessage: qsTr("Orbit the vehicle around the current location.") readonly property string orbitMessage: qsTr("Orbit the vehicle around the current location.")
readonly property string landAbortMessage: qsTr("Abort the landing sequence.") readonly property string landAbortMessage: qsTr("Abort the landing sequence.")
readonly property string pauseMessage: qsTr("Pause the vehicle at it's current position.") readonly property string pauseMessage: qsTr("Pause the vehicle at it's current position.")
readonly property string mvPauseMessage: qsTr("Pause all vehicles at their current position.")
readonly property int actionRTL: 1 readonly property int actionRTL: 1
readonly property int actionLand: 2 readonly property int actionLand: 2
@ -81,6 +82,8 @@ Item {
readonly property int actionResumeMission: 14 readonly property int actionResumeMission: 14
readonly property int actionResumeMissionReady: 15 readonly property int actionResumeMissionReady: 15
readonly property int actionPause: 16 readonly property int actionPause: 16
readonly property int actionMVPause: 17
readonly property int actionMVStartMission: 18
property bool showEmergenyStop: !_hideEmergenyStop && _activeVehicle && _vehicleArmed && _vehicleFlying property bool showEmergenyStop: !_hideEmergenyStop && _activeVehicle && _vehicleArmed && _vehicleFlying
property bool showArm: _activeVehicle && !_vehicleArmed property bool showArm: _activeVehicle && !_vehicleArmed
@ -90,7 +93,7 @@ Item {
property bool showLand: _activeVehicle && _activeVehicle.guidedModeSupported && _vehicleArmed && !_activeVehicle.fixedWing && !_vehicleInLandMode property bool showLand: _activeVehicle && _activeVehicle.guidedModeSupported && _vehicleArmed && !_activeVehicle.fixedWing && !_vehicleInLandMode
property bool showStartMission: _activeVehicle && _missionAvailable && !_missionActive && !_vehicleFlying property bool showStartMission: _activeVehicle && _missionAvailable && !_missionActive && !_vehicleFlying
property bool showContinueMission: _activeVehicle && _missionAvailable && !_missionActive && _vehicleFlying && (_currentMissionIndex < missionController.visualItems.count - 1) property bool showContinueMission: _activeVehicle && _missionAvailable && !_missionActive && _vehicleFlying && (_currentMissionIndex < missionController.visualItems.count - 1)
property bool showResumeMission: _activeVehicle && !_vehicleFlying && _missionAvailable && _resumeMissionIndex > 0 && (_resumeMissionIndex < missionController.visualItems.count - 2) property bool showResumeMission: _activeVehicle && !_vehicleArmed && _vehicleWasFlying && _missionAvailable && _resumeMissionIndex > 0 && (_resumeMissionIndex < missionController.visualItems.count - 2)
property bool showPause: _activeVehicle && _vehicleArmed && _activeVehicle.pauseVehicleSupported && _vehicleFlying && !_vehiclePaused property bool showPause: _activeVehicle && _vehicleArmed && _activeVehicle.pauseVehicleSupported && _vehicleFlying && !_vehiclePaused
property bool showChangeAlt: (_activeVehicle && _vehicleFlying) && _activeVehicle.guidedModeSupported && _vehicleArmed && !_missionActive property bool showChangeAlt: (_activeVehicle && _vehicleFlying) && _activeVehicle.guidedModeSupported && _vehicleArmed && !_missionActive
property bool showOrbit: !_hideOrbit && _activeVehicle && _vehicleFlying && _activeVehicle.orbitModeSupported && _vehicleArmed && !_missionActive property bool showOrbit: !_hideOrbit && _activeVehicle && _vehicleFlying && _activeVehicle.orbitModeSupported && _vehicleArmed && !_missionActive
@ -114,6 +117,7 @@ Item {
property int _resumeMissionIndex: missionController.resumeMissionIndex property int _resumeMissionIndex: missionController.resumeMissionIndex
property bool _hideEmergenyStop: !QGroundControl.corePlugin.options.guidedBarShowEmergencyStop property bool _hideEmergenyStop: !QGroundControl.corePlugin.options.guidedBarShowEmergencyStop
property bool _hideOrbit: !QGroundControl.corePlugin.options.guidedBarShowOrbit property bool _hideOrbit: !QGroundControl.corePlugin.options.guidedBarShowOrbit
property bool _vehicleWasFlying: false
// This is a temporary hack to debug a problem with RTL and Pause being disabled at the wrong time // This is a temporary hack to debug a problem with RTL and Pause being disabled at the wrong time
@ -128,7 +132,6 @@ Item {
Component.onCompleted: _outputState() Component.onCompleted: _outputState()
on_ActiveVehicleChanged: _outputState() on_ActiveVehicleChanged: _outputState()
on_VehicleArmedChanged: _outputState() on_VehicleArmedChanged: _outputState()
on_VehicleFlyingChanged: _outputState()
on_VehicleInRTLModeChanged: _outputState() on_VehicleInRTLModeChanged: _outputState()
on_VehiclePausedChanged: _outputState() on_VehiclePausedChanged: _outputState()
on__FlightModeChanged: _outputState() on__FlightModeChanged: _outputState()
@ -137,6 +140,15 @@ Item {
// End of hack // End of hack
on_VehicleFlyingChanged: {
_outputState()
if (!_vehicleFlying) {
// We use _vehicleWasFLying to help trigger Resume Mission only if the vehicle actually flew and came back down.
// Otherwise it may trigger during the Start Mission sequence due to signal ordering or armed and resume mission index.
_vehicleWasFlying = true
}
}
property var _actionData property var _actionData
on_CurrentMissionIndexChanged: console.log("_currentMissionIndex", _currentMissionIndex) on_CurrentMissionIndexChanged: console.log("_currentMissionIndex", _currentMissionIndex)
@ -186,6 +198,11 @@ Item {
confirmDialog.message = startMissionMessage confirmDialog.message = startMissionMessage
confirmDialog.hideTrigger = Qt.binding(function() { return !showStartMission }) confirmDialog.hideTrigger = Qt.binding(function() { return !showStartMission })
break; break;
case actionMVStartMission:
confirmDialog.title = startMissionTitle
confirmDialog.message = startMissionMessage
confirmDialog.hideTrigger = true
break;
case actionContinueMission: case actionContinueMission:
confirmDialog.title = continueMissionTitle confirmDialog.title = continueMissionTitle
confirmDialog.message = continueMissionMessage confirmDialog.message = continueMissionMessage
@ -242,6 +259,11 @@ Item {
confirmDialog.message = pauseMessage confirmDialog.message = pauseMessage
confirmDialog.hideTrigger = Qt.binding(function() { return !showPause }) confirmDialog.hideTrigger = Qt.binding(function() { return !showPause })
break; break;
case actionMVPause:
confirmDialog.title = pauseTitle
confirmDialog.message = mvPauseMessage
confirmDialog.hideTrigger = true
break;
default: default:
console.warn("Unknown actionCode", actionCode) console.warn("Unknown actionCode", actionCode)
return return
@ -265,12 +287,20 @@ Item {
missionController.resumeMission(missionController.resumeMissionIndex) missionController.resumeMission(missionController.resumeMissionIndex)
break break
case actionResumeMissionReady: case actionResumeMissionReady:
_vehicleWasFlying = false
_activeVehicle.startMission() _activeVehicle.startMission()
break break
case actionStartMission: case actionStartMission:
case actionContinueMission: case actionContinueMission:
_activeVehicle.startMission() _activeVehicle.startMission()
break break
case actionMVStartMission:
var rgVehicle = QGroundControl.multiVehicleManager.vehicles
for (var i=0; i<rgVehicle.count; i++) {
var vehicle = rgVehicle.get(i)
vehicle.startMission()
}
break
case actionArm: case actionArm:
_activeVehicle.armed = true _activeVehicle.armed = true
break break
@ -298,6 +328,13 @@ Item {
case actionPause: case actionPause:
_activeVehicle.pauseVehicle() _activeVehicle.pauseVehicle()
break break
case actionMVPause:
var rgVehicle = QGroundControl.multiVehicleManager.vehicles
for (var i=0; i<rgVehicle.count; i++) {
var vehicle = rgVehicle.get(i)
vehicle.pauseVehicle()
}
break
default: default:
console.warn(qsTr("Internal error: unknown actionCode"), actionCode) console.warn(qsTr("Internal error: unknown actionCode"), actionCode)
break break

135
src/FlightDisplay/MultiVehicleList.qml

@ -18,55 +18,93 @@ import QGroundControl.Palette 1.0
import QGroundControl.Vehicle 1.0 import QGroundControl.Vehicle 1.0
import QGroundControl.FlightMap 1.0 import QGroundControl.FlightMap 1.0
Item {
property var guidedActionsController
property real _margin: ScreenTools.defaultFontPixelWidth / 2
property real _widgetHeight: ScreenTools.defaultFontPixelHeight * 3
property color _textColor: "black"
property real _rectOpacity: 0.8
QGCPalette { id: qgcPal }
NoMouseThroughRectangle {
id: mvCommands
anchors.left: parent.left
anchors.right: parent.right
height: mvCommandsColumn.height + (_margin *2)
color: qgcPal.missionItemEditor
opacity: _rectOpacity
radius: _margin
Column {
id: mvCommandsColumn
anchors.margins: _margin
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("The following commands will be applied to all vehicles")
color: _textColor
wrapMode: Text.WordWrap
font.pointSize: ScreenTools.smallFontPointSize
}
Row {
spacing: _margin
QGCButton {
text: "Pause"
onClicked: guidedActionsController.confirmAction(guidedActionsController.actionMVPause)
}
QGCButton {
text: "Start Mision"
onClicked: guidedActionsController.confirmAction(guidedActionsController.actionMVStartMission)
}
}
}
}
QGCListView { QGCListView {
id: missionItemEditorListView id: missionItemEditorListView
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: _margin
anchors.top: mvCommands.bottom
anchors.bottom: parent.bottom
spacing: ScreenTools.defaultFontPixelHeight / 2 spacing: ScreenTools.defaultFontPixelHeight / 2
orientation: ListView.Vertical orientation: ListView.Vertical
model: QGroundControl.multiVehicleManager.vehicles model: QGroundControl.multiVehicleManager.vehicles
cacheBuffer: _cacheBuffer < 0 ? 0 : _cacheBuffer cacheBuffer: _cacheBuffer < 0 ? 0 : _cacheBuffer
clip: true clip: true
property real _margin: ScreenTools.defaultFontPixelWidth / 2
property real _cacheBuffer: height * 2 property real _cacheBuffer: height * 2
property real _widgetHeight: ScreenTools.defaultFontPixelHeight * 3
delegate: Rectangle { delegate: Rectangle {
width: parent.width width: parent.width
height: innerColumn.y + innerColumn.height + _margin height: innerColumn.y + innerColumn.height + _margin
color: qgcPal.missionItemEditor color: qgcPal.missionItemEditor
opacity: 0.8 opacity: _rectOpacity
radius: _margin radius: _margin
property var _vehicle: object property var _vehicle: object
property color _textColor: "black"
QGCPalette { id: qgcPal } ColumnLayout {
id: innerColumn
Row {
id: widgetLayout
anchors.margins: _margin anchors.margins: _margin
anchors.top: parent.top anchors.top: parent.top
anchors.right: parent.right anchors.left: parent.left
spacing: ScreenTools.defaultFontPixelWidth / 2 anchors.right: parent.left
layoutDirection: Qt.RightToLeft spacing: _margin
QGCCompassWidget {
size: _widgetHeight
vehicle: _vehicle
}
QGCAttitudeWidget {
size: _widgetHeight
vehicle: _vehicle
}
}
RowLayout { RowLayout {
anchors.top: widgetLayout.top
anchors.bottom: widgetLayout.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: widgetLayout.left anchors.right: parent.left
spacing: ScreenTools.defaultFontPixelWidth / 2
QGCLabel { QGCLabel {
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
@ -74,27 +112,34 @@ QGCListView {
color: _textColor color: _textColor
} }
ColumnLayout {
Layout.alignment: Qt.AlignCenter
spacing: _margin
FlightModeMenu { FlightModeMenu {
anchors.horizontalCenter: parent.horizontalCenter
font.pointSize: ScreenTools.largeFontPointSize font.pointSize: ScreenTools.largeFontPointSize
color: _textColor color: _textColor
activeVehicle: _vehicle activeVehicle: _vehicle
} }
QGCLabel {
anchors.horizontalCenter: parent.horizontalCenter
text: _vehicle.armed ? qsTr("Armed") : qsTr("Disarmed")
color: _textColor
}
} }
Column { QGCCompassWidget {
id: innerColumn size: _widgetHeight
anchors.margins: _margin vehicle: _vehicle
anchors.left: parent.left }
anchors.right: parent.right
anchors.top: widgetLayout.bottom
spacing: _margin
Rectangle { QGCAttitudeWidget {
anchors.left: parent.left size: _widgetHeight
anchors.right: parent.right vehicle: _vehicle
height: 5
color: "green"
} }
} // RowLayout
Row { Row {
spacing: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelWidth
@ -106,13 +151,13 @@ QGCListView {
} }
QGCButton { QGCButton {
text: "Start" text: "Start Mission"
visible: _vehicle.armed && _vehicle.flightMode != _vehicle.missionFlightMode visible: _vehicle.armed && _vehicle.flightMode != _vehicle.missionFlightMode
onClicked: _vehicle.flightMode = _vehicle.missionFlightMode onClicked: _vehicle.startMission()
} }
QGCButton { QGCButton {
text: "Stop" text: "Pause"
visible: _vehicle.armed && _vehicle.pauseVehicleSupported visible: _vehicle.armed && _vehicle.pauseVehicleSupported
onClicked: _vehicle.pauseVehicle() onClicked: _vehicle.pauseVehicle()
} }
@ -128,8 +173,8 @@ QGCListView {
visible: _vehicle.armed && _vehicle.flightMode != _vehicle.takeControlFlightMode visible: _vehicle.armed && _vehicle.flightMode != _vehicle.takeControlFlightMode
onClicked: _vehicle.flightMode = _vehicle.takeControlFlightMode onClicked: _vehicle.flightMode = _vehicle.takeControlFlightMode
} }
} // Row
} } // ColumnLayout
} } // delegate - Rectangle
}
} // QGCListView } // QGCListView
} // Item

66
src/FlightMap/Images/adsbVehicle.svg

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<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="0 0 72 72"
style="enable-background:new 0 0 72 72;"
xml:space="preserve"
inkscape:version="0.91 r13725"
sodipodi:docname="adsbVehicle.svg"><metadata
id="metadata23"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs21" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="664"
inkscape:window-height="480"
id="namedview19"
showgrid="false"
inkscape:zoom="3.2777778"
inkscape:cx="36"
inkscape:cy="36"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="g7" /><style
type="text/css"
id="style3">
.st0{fill:#C72B27;}
.st1{fill:#7F0036;}
.st2{fill:#EE3424;}
</style><g
id="g5"><g
id="g7"><polygon
class="st0"
points="35.5,2.118 35.5,53.691 1.118,70.882 "
id="polygon9"
style="fill:#24d3ee;fill-opacity:1" /><path
class="st1"
d="M35,4.236v49.146L2.236,69.764L35,4.236 M36,0L0,72l36-18V0L36,0z"
id="path11" /></g><g
id="g13"><polygon
class="st2"
points="36.5,53.691 36.5,2.118 70.882,70.882 "
id="polygon15"
style="fill:#24d3ee;fill-opacity:1" /><path
class="st1"
d="M37,4.236l32.764,65.528L37,53.382V4.236 M36,0v54l36,18L36,0L36,0z"
id="path17" /></g></g></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

69
src/FlightMap/MapItems/VehicleMapItem.qml

@ -7,38 +7,81 @@
* *
****************************************************************************/ ****************************************************************************/
/// @file
/// @author Don Gagne <don@thegagnes.com>
import QtQuick 2.3 import QtQuick 2.3
import QtLocation 5.3 import QtLocation 5.3
import QtPositioning 5.3 import QtPositioning 5.3
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0 import QGroundControl.ScreenTools 1.0
import QGroundControl.Vehicle 1.0 import QGroundControl.Vehicle 1.0
import QGroundControl.Controls 1.0
/// Marker for displaying a vehicle location on the map /// Marker for displaying a vehicle location on the map
MapQuickItem { MapQuickItem {
property var vehicle ///< Vehicle object property var vehicle /// Vehicle object, undefined for ADSB vehicle
property bool isSatellite: false ///< true: satellite map is showing property var map
property real size: ScreenTools.defaultFontPixelHeight * 5 property double altitude: Number.NaN ///< NAN to not show
property string callsign: "" ///< Vehicle callsign
property double heading: vehicle ? vehicle.heading.value : Number.NaN ///< Vehicle heading, NAN for none
property real size: _adsbVehicle ? _adsbSize : _uavSize /// Size for icon
anchorPoint.x: vehicleItem.width / 2
anchorPoint.y: vehicleItem.height / 2
visible: coordinate.isValid
property bool _adsbVehicle: vehicle ? false : true
property real _uavSize: ScreenTools.defaultFontPixelHeight * 5
property real _adsbSize: ScreenTools.defaultFontPixelHeight * 1.5
property var _map: map
property bool _multiVehicle: QGroundControl.multiVehicleManager.vehicles.count > 1
anchorPoint.x: vehicleIcon.width / 2 sourceItem: Item {
anchorPoint.y: vehicleIcon.height / 2 id: vehicleItem
visible: vehicle && vehicle.coordinate.isValid width: vehicleIcon.width
height: vehicleIcon.height
opacity: vehicle ? (vehicle.active ? 1.0 : 0.5) : 1.0
sourceItem: Image { Image {
id: vehicleIcon id: vehicleIcon
source: isSatellite ? vehicle.vehicleImageOpaque : vehicle.vehicleImageOutline source: _adsbVehicle ? "/qmlimages/adsbVehicle.svg" : vehicle.vehicleImageOpaque
mipmap: true mipmap: true
width: size width: size
sourceSize.width: size sourceSize.width: size
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
transform: Rotation { transform: Rotation {
origin.x: vehicleIcon.width / 2 origin.x: vehicleIcon.width / 2
origin.y: vehicleIcon.height / 2 origin.y: vehicleIcon.height / 2
angle: vehicle ? vehicle.heading.value : 0 angle: isNaN(heading) ? 0 : heading
}
}
QGCMapLabel {
id: vehicleLabel
anchors.top: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
map: _map
text: vehicleLabelText
font.pointSize: ScreenTools.smallFontPointSize
visible: _adsbVehicle ? !isNaN(altitude) : _multiVehicle
property string vehicleLabelText: visible ?
(_adsbVehicle ?
QGroundControl.metersToAppSettingsDistanceUnits(altitude).toFixed(0) + " " + QGroundControl.appSettingsDistanceUnitsString :
(_multiVehicle ? qsTr("Vehicle %1").arg(vehicle.id) : "")) :
""
}
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 : ""
} }
} }
} }

2
src/MissionManager/GeoFenceController.cc

@ -84,6 +84,8 @@ void GeoFenceController::_signalAll(void)
emit polygonEnabledChanged(polygonEnabled()); emit polygonEnabledChanged(polygonEnabled());
emit polygonSupportedChanged(polygonSupported()); emit polygonSupportedChanged(polygonSupported());
emit dirtyChanged(dirty()); emit dirtyChanged(dirty());
emit paramsChanged(params());
emit paramLabelsChanged(paramLabels());
} }
void GeoFenceController::managerVehicleChanged(Vehicle* managerVehicle) void GeoFenceController::managerVehicleChanged(Vehicle* managerVehicle)

5
src/MissionManager/MissionController.cc

@ -158,7 +158,10 @@ void MissionController::_newMissionItemsAvailableFromVehicle(bool removeAllReque
qWarning() << "First item is not settings item"; qWarning() << "First item is not settings item";
return; return;
} }
settingsItem->setCoordinate(newMissionItems[0]->coordinate()); MissionItem* fakeHomeItem = newMissionItems[0];
if (fakeHomeItem->coordinate().latitude() != 0 || fakeHomeItem->coordinate().longitude() != 0) {
settingsItem->setCoordinate(fakeHomeItem->coordinate());
}
i = 1; i = 1;
} }

4
src/MissionManager/Survey.SettingsGroup.json

@ -64,7 +64,7 @@
"min": 0, "min": 0,
"max": 85, "max": 85,
"units": "%", "units": "%",
"defaultValue": 10 "defaultValue": 70
}, },
{ {
"name": "SideOverlap", "name": "SideOverlap",
@ -74,7 +74,7 @@
"min": 0, "min": 0,
"max": 85, "max": 85,
"units": "%", "units": "%",
"defaultValue": 10 "defaultValue": 70
}, },
{ {
"name": "CameraSensorWidth", "name": "CameraSensorWidth",

2
src/PlanView/PlanView.qml

@ -366,7 +366,7 @@ QGCView {
VehicleMapItem { VehicleMapItem {
vehicle: object vehicle: object
coordinate: object.coordinate coordinate: object.coordinate
isSatellite: editorMap.isSatelliteMap map: editorMap
size: ScreenTools.defaultFontPixelHeight * 3 size: ScreenTools.defaultFontPixelHeight * 3
z: QGroundControl.zOrderMapItems - 1 z: QGroundControl.zOrderMapItems - 1
} }

71
src/Vehicle/ADSBVehicle.cc

@ -0,0 +1,71 @@
/****************************************************************************
*
* (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 <QDebug>
#include <QtMath>
ADSBVehicle::ADSBVehicle(mavlink_adsb_vehicle_t& adsbVehicle, QObject* parent)
: QObject (parent)
, _icaoAddress (adsbVehicle.ICAO_address)
, _callsign (adsbVehicle.callsign)
, _altitude (NAN)
, _heading (NAN)
{
if (!(adsbVehicle.flags | ADSB_FLAGS_VALID_COORDS)) {
qWarning() << "At least coords must be valid";
return;
}
update(adsbVehicle);
}
void ADSBVehicle::update(mavlink_adsb_vehicle_t& adsbVehicle)
{
if (_icaoAddress != adsbVehicle.ICAO_address) {
qWarning() << "ICAO address mismatch expected:actual" << _icaoAddress << adsbVehicle.ICAO_address;
return;
}
if (!(adsbVehicle.flags | ADSB_FLAGS_VALID_COORDS)) {
return;
}
QString currCallsign(adsbVehicle.callsign);
if (currCallsign != _callsign) {
_callsign = currCallsign;
emit callsignChanged(_callsign);
}
QGeoCoordinate newCoordinate(adsbVehicle.lat / 1e7, adsbVehicle.lon / 1e7);
if (newCoordinate != _coordinate) {
_coordinate = newCoordinate;
emit coordinateChanged(_coordinate);
}
double newAltitude = NAN;
if (adsbVehicle.flags | ADSB_FLAGS_VALID_ALTITUDE) {
newAltitude = (double)adsbVehicle.altitude / 1e3;
}
if (!(qIsNaN(newAltitude) && qIsNaN(_altitude)) && !qFuzzyCompare(newAltitude, _altitude)) {
_altitude = newAltitude;
emit altitudeChanged(_altitude);
}
double newHeading = NAN;
if (adsbVehicle.flags | ADSB_FLAGS_VALID_HEADING) {
newHeading = (double)adsbVehicle.heading / 100.0;
}
if (!(qIsNaN(newHeading) && qIsNaN(_heading)) && !qFuzzyCompare(newHeading, _heading)) {
_heading = newHeading;
emit headingChanged(_heading);
}
}

51
src/Vehicle/ADSBVehicle.h

@ -0,0 +1,51 @@
/****************************************************************************
*
* (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 <QObject>
#include <QGeoCoordinate>
#include "QGCMAVLink.h"
class ADSBVehicle : public QObject
{
Q_OBJECT
public:
ADSBVehicle(mavlink_adsb_vehicle_t& adsbVehicle, QObject* parent = NULL);
Q_PROPERTY(int icaoAddress READ icaoAddress CONSTANT)
Q_PROPERTY(QString callsign READ callsign NOTIFY callsignChanged)
Q_PROPERTY(QGeoCoordinate coordinate READ coordinate NOTIFY coordinateChanged)
Q_PROPERTY(double altitude READ altitude NOTIFY altitudeChanged) // NaN for not available
Q_PROPERTY(double heading READ heading NOTIFY headingChanged) // NaN for not available
int icaoAddress (void) const { return _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; }
/// Update the vehicle with new information
void update(mavlink_adsb_vehicle_t& adsbVehicle);
signals:
void coordinateChanged(QGeoCoordinate coordinate);
void callsignChanged(QString callsign);
void altitudeChanged(double altitude);
void headingChanged(double heading);
private:
uint32_t _icaoAddress;
QString _callsign;
QGeoCoordinate _coordinate;
double _altitude;
double _heading;
};

86
src/Vehicle/Vehicle.cc

@ -30,6 +30,8 @@
#include "QGroundControlQmlGlobal.h" #include "QGroundControlQmlGlobal.h"
#include "SettingsManager.h" #include "SettingsManager.h"
#include "QGCQGeoCoordinate.h" #include "QGCQGeoCoordinate.h"
#include "QGCCorePlugin.h"
#include "ADSBVehicle.h"
QGC_LOGGING_CATEGORY(VehicleLog, "VehicleLog") QGC_LOGGING_CATEGORY(VehicleLog, "VehicleLog")
@ -79,7 +81,8 @@ Vehicle::Vehicle(LinkInterface* link,
, _autopilotPlugin(NULL) , _autopilotPlugin(NULL)
, _mavlink(NULL) , _mavlink(NULL)
, _soloFirmware(false) , _soloFirmware(false)
, _settingsManager(qgcApp()->toolbox()->settingsManager()) , _toolbox(qgcApp()->toolbox())
, _settingsManager(_toolbox->settingsManager())
, _joystickMode(JoystickModeRC) , _joystickMode(JoystickModeRC)
, _joystickEnabled(false) , _joystickEnabled(false)
, _uas(NULL) , _uas(NULL)
@ -166,7 +169,7 @@ Vehicle::Vehicle(LinkInterface* link,
connect(_joystickManager, &JoystickManager::activeJoystickChanged, this, &Vehicle::_activeJoystickChanged); connect(_joystickManager, &JoystickManager::activeJoystickChanged, this, &Vehicle::_activeJoystickChanged);
_mavlink = qgcApp()->toolbox()->mavlinkProtocol(); _mavlink = _toolbox->mavlinkProtocol();
connect(_mavlink, &MAVLinkProtocol::messageReceived, this, &Vehicle::_mavlinkMessageReceived); connect(_mavlink, &MAVLinkProtocol::messageReceived, this, &Vehicle::_mavlinkMessageReceived);
@ -183,7 +186,7 @@ Vehicle::Vehicle(LinkInterface* link,
_autopilotPlugin = _firmwarePlugin->autopilotPlugin(this); _autopilotPlugin = _firmwarePlugin->autopilotPlugin(this);
// connect this vehicle to the follow me handle manager // connect this vehicle to the follow me handle manager
connect(this, &Vehicle::flightModeChanged,qgcApp()->toolbox()->followMe(), &FollowMe::followMeHandleManager); connect(this, &Vehicle::flightModeChanged,_toolbox->followMe(), &FollowMe::followMeHandleManager);
// PreArm Error self-destruct timer // PreArm Error self-destruct timer
connect(&_prearmErrorTimer, &QTimer::timeout, this, &Vehicle::_prearmErrorTimeout); connect(&_prearmErrorTimer, &QTimer::timeout, this, &Vehicle::_prearmErrorTimeout);
@ -204,8 +207,8 @@ Vehicle::Vehicle(LinkInterface* link,
_mav = uas(); _mav = uas();
// Listen for system messages // Listen for system messages
connect(qgcApp()->toolbox()->uasMessageHandler(), &UASMessageHandler::textMessageCountChanged, this, &Vehicle::_handleTextMessage); connect(_toolbox->uasMessageHandler(), &UASMessageHandler::textMessageCountChanged, this, &Vehicle::_handleTextMessage);
connect(qgcApp()->toolbox()->uasMessageHandler(), &UASMessageHandler::textMessageReceived, this, &Vehicle::_handletextMessageReceived); connect(_toolbox->uasMessageHandler(), &UASMessageHandler::textMessageReceived, this, &Vehicle::_handletextMessageReceived);
// Now connect the new UAS // Now connect the new UAS
connect(_mav, SIGNAL(attitudeChanged (UASInterface*,double,double,double,quint64)), this, SLOT(_updateAttitude(UASInterface*, double, double, double, quint64))); connect(_mav, SIGNAL(attitudeChanged (UASInterface*,double,double,double,quint64)), this, SLOT(_updateAttitude(UASInterface*, double, double, double, quint64)));
connect(_mav, SIGNAL(attitudeChanged (UASInterface*,int,double,double,double,quint64)), this, SLOT(_updateAttitude(UASInterface*,int,double, double, double, quint64))); connect(_mav, SIGNAL(attitudeChanged (UASInterface*,int,double,double,double,quint64)), this, SLOT(_updateAttitude(UASInterface*,int,double, double, double, quint64)));
@ -244,7 +247,8 @@ Vehicle::Vehicle(MAV_AUTOPILOT firmwareType,
, _autopilotPlugin(NULL) , _autopilotPlugin(NULL)
, _mavlink(NULL) , _mavlink(NULL)
, _soloFirmware(false) , _soloFirmware(false)
, _settingsManager(qgcApp()->toolbox()->settingsManager()) , _toolbox(qgcApp()->toolbox())
, _settingsManager(_toolbox->settingsManager())
, _joystickMode(JoystickModeRC) , _joystickMode(JoystickModeRC)
, _joystickEnabled(false) , _joystickEnabled(false)
, _uas(NULL) , _uas(NULL)
@ -510,6 +514,11 @@ void Vehicle::_mavlinkMessageReceived(LinkInterface* link, mavlink_message_t mes
return; return;
} }
// Give the Core Plugin access to all mavlink traffic
if (!_toolbox->corePlugin()->mavlinkMessage(this, link, message)) {
return;
}
switch (message.msgid) { switch (message.msgid) {
case MAVLINK_MSG_ID_HOME_POSITION: case MAVLINK_MSG_ID_HOME_POSITION:
_handleHomePosition(message); _handleHomePosition(message);
@ -592,10 +601,12 @@ void Vehicle::_mavlinkMessageReceived(LinkInterface* link, mavlink_message_t mes
case MAVLINK_MSG_ID_CAMERA_FEEDBACK: case MAVLINK_MSG_ID_CAMERA_FEEDBACK:
_handleCameraFeedback(message); _handleCameraFeedback(message);
break; break;
case MAVLINK_MSG_ID_CAMERA_IMAGE_CAPTURED: case MAVLINK_MSG_ID_CAMERA_IMAGE_CAPTURED:
_handleCameraImageCaptured(message); _handleCameraImageCaptured(message);
break; break;
case MAVLINK_MSG_ID_ADSB_VEHICLE:
_handleADSBVehicle(message);
break;
case MAVLINK_MSG_ID_SERIAL_CONTROL: case MAVLINK_MSG_ID_SERIAL_CONTROL:
{ {
@ -681,8 +692,8 @@ void Vehicle::_handleGlobalPositionInt(mavlink_message_t& message)
mavlink_global_position_int_t globalPositionInt; mavlink_global_position_int_t globalPositionInt;
mavlink_msg_global_position_int_decode(&message, &globalPositionInt); mavlink_msg_global_position_int_decode(&message, &globalPositionInt);
// ArduPilot sends bogus GLOBAL_POSITION_INT messages with lat/lat/alt 0/0/0 even when it has not gps signal // ArduPilot sends bogus GLOBAL_POSITION_INT messages with lat/lat 0/0 even when it has not gps signal
if (globalPositionInt.lat == 0 && globalPositionInt.lon == 0 && globalPositionInt.alt == 0) { if (globalPositionInt.lat == 0 && globalPositionInt.lon == 0) {
return; return;
} }
@ -810,7 +821,7 @@ void Vehicle::_handleCommandAck(mavlink_message_t& message)
emit mavCommandResult(_id, message.compid, ack.command, ack.result, false /* noResponsefromVehicle */); emit mavCommandResult(_id, message.compid, ack.command, ack.result, false /* noResponsefromVehicle */);
if (showError) { if (showError) {
QString commandName = qgcApp()->toolbox()->missionCommandTree()->friendlyName((MAV_CMD)ack.command); QString commandName = _toolbox->missionCommandTree()->friendlyName((MAV_CMD)ack.command);
switch (ack.result) { switch (ack.result) {
case MAV_RESULT_TEMPORARILY_REJECTED: case MAV_RESULT_TEMPORARILY_REJECTED:
@ -1193,8 +1204,8 @@ void Vehicle::_addLink(LinkInterface* link)
qCDebug(VehicleLog) << "_addLink:" << QString("%1").arg((ulong)link, 0, 16); qCDebug(VehicleLog) << "_addLink:" << QString("%1").arg((ulong)link, 0, 16);
_links += link; _links += link;
_updatePriorityLink(); _updatePriorityLink();
connect(qgcApp()->toolbox()->linkManager(), &LinkManager::linkInactive, this, &Vehicle::_linkInactiveOrDeleted); connect(_toolbox->linkManager(), &LinkManager::linkInactive, this, &Vehicle::_linkInactiveOrDeleted);
connect(qgcApp()->toolbox()->linkManager(), &LinkManager::linkDeleted, this, &Vehicle::_linkInactiveOrDeleted); connect(_toolbox->linkManager(), &LinkManager::linkDeleted, this, &Vehicle::_linkInactiveOrDeleted);
} }
} }
@ -1283,7 +1294,7 @@ void Vehicle::_updatePriorityLink(void)
} }
if (newPriorityLink) { if (newPriorityLink) {
_priorityLink = qgcApp()->toolbox()->linkManager()->sharedLinkInterfacePointerForLink(newPriorityLink); _priorityLink = _toolbox->linkManager()->sharedLinkInterfacePointerForLink(newPriorityLink);
} }
} }
@ -1360,7 +1371,7 @@ QString Vehicle::getMavIconColor()
QString Vehicle::formatedMessages() QString Vehicle::formatedMessages()
{ {
QString messages; QString messages;
foreach(UASMessage* message, qgcApp()->toolbox()->uasMessageHandler()->messages()) { foreach(UASMessage* message, _toolbox->uasMessageHandler()->messages()) {
messages += message->getFormatedText(); messages += message->getFormatedText();
} }
return messages; return messages;
@ -1368,7 +1379,7 @@ QString Vehicle::formatedMessages()
void Vehicle::clearMessages() void Vehicle::clearMessages()
{ {
qgcApp()->toolbox()->uasMessageHandler()->clearMessages(); _toolbox->uasMessageHandler()->clearMessages();
} }
void Vehicle::_handletextMessageReceived(UASMessage* message) void Vehicle::_handletextMessageReceived(UASMessage* message)
@ -1396,7 +1407,7 @@ void Vehicle::_handleTextMessage(int newCount)
return; return;
} }
UASMessageHandler* pMh = qgcApp()->toolbox()->uasMessageHandler(); UASMessageHandler* pMh = _toolbox->uasMessageHandler();
MessageType_t type = newCount ? _currentMessageType : MessageNone; MessageType_t type = newCount ? _currentMessageType : MessageNone;
int errorCount = _currentErrorCount; int errorCount = _currentErrorCount;
int warnCount = _currentWarningCount; int warnCount = _currentWarningCount;
@ -1482,7 +1493,7 @@ void Vehicle::_loadSettings(void)
} }
// Joystick enabled is a global setting so first make sure there are any joysticks connected // Joystick enabled is a global setting so first make sure there are any joysticks connected
if (qgcApp()->toolbox()->joystickManager()->joysticks().count()) { if (_toolbox->joystickManager()->joysticks().count()) {
setJoystickEnabled(settings.value(_joystickEnabledSettingsKey, false).toBool()); setJoystickEnabled(settings.value(_joystickEnabledSettingsKey, false).toBool());
} }
} }
@ -1497,7 +1508,7 @@ void Vehicle::_saveSettings(void)
// The joystick enabled setting should only be changed if a joystick is present // The joystick enabled setting should only be changed if a joystick is present
// since the checkbox can only be clicked if one is present // since the checkbox can only be clicked if one is present
if (qgcApp()->toolbox()->joystickManager()->joysticks().count()) { if (_toolbox->joystickManager()->joysticks().count()) {
settings.setValue(_joystickEnabledSettingsKey, _joystickEnabled); settings.setValue(_joystickEnabledSettingsKey, _joystickEnabled);
} }
} }
@ -1568,7 +1579,10 @@ bool Vehicle::active(void)
void Vehicle::setActive(bool active) void Vehicle::setActive(bool active)
{ {
if (_active != active) {
_active = active; _active = active;
emit activeChanged(_active);
}
_startJoystick(_active); _startJoystick(_active);
} }
@ -1840,11 +1854,11 @@ void Vehicle::disconnectInactiveVehicle(void)
// Vehicle is no longer communicating with us, disconnect all links // Vehicle is no longer communicating with us, disconnect all links
LinkManager* linkMgr = qgcApp()->toolbox()->linkManager(); LinkManager* linkMgr = _toolbox->linkManager();
for (int i=0; i<_links.count(); i++) { for (int i=0; i<_links.count(); i++) {
// FIXME: This linkInUse check is a hack fix for multiple vehicles on the same link. // FIXME: This linkInUse check is a hack fix for multiple vehicles on the same link.
// The real fix requires significant restructuring which will come later. // The real fix requires significant restructuring which will come later.
if (!qgcApp()->toolbox()->multiVehicleManager()->linkInUse(_links[i], this)) { if (!_toolbox->multiVehicleManager()->linkInUse(_links[i], this)) {
linkMgr->disconnectLink(_links[i]); linkMgr->disconnectLink(_links[i]);
} }
} }
@ -1855,7 +1869,7 @@ void Vehicle::_imageReady(UASInterface*)
if(_uas) if(_uas)
{ {
QImage img = _uas->getImage(); QImage img = _uas->getImage();
qgcApp()->toolbox()->imageProvider()->setImage(&img, _id); _toolbox->imageProvider()->setImage(&img, _id);
_flowImageIndex++; _flowImageIndex++;
emit flowImageIndexChanged(); emit flowImageIndexChanged();
} }
@ -1920,7 +1934,7 @@ void Vehicle::_connectionActive(void)
void Vehicle::_say(const QString& text) void Vehicle::_say(const QString& text)
{ {
qgcApp()->toolbox()->audioOutput()->say(text.toLower()); _toolbox->audioOutput()->say(text.toLower());
} }
bool Vehicle::fixedWing(void) const bool Vehicle::fixedWing(void) const
@ -2021,7 +2035,7 @@ QString Vehicle::vehicleTypeName() const {
/// Returns the string to speak to identify the vehicle /// Returns the string to speak to identify the vehicle
QString Vehicle::_vehicleIdSpeech(void) QString Vehicle::_vehicleIdSpeech(void)
{ {
if (qgcApp()->toolbox()->multiVehicleManager()->vehicles()->count() > 1) { if (_toolbox->multiVehicleManager()->vehicles()->count() > 1) {
return QString("vehicle %1").arg(id()); return QString("vehicle %1").arg(id());
} else { } else {
return QString(); return QString();
@ -2232,7 +2246,7 @@ void Vehicle::_sendMavCommandAgain(void)
emit mavCommandResult(_id, queuedCommand.component, queuedCommand.command, MAV_RESULT_FAILED, true /* noResponsefromVehicle */); emit mavCommandResult(_id, queuedCommand.component, queuedCommand.command, MAV_RESULT_FAILED, true /* noResponsefromVehicle */);
if (queuedCommand.showError) { if (queuedCommand.showError) {
qgcApp()->showMessage(tr("Vehicle did not respond to command: %1").arg(qgcApp()->toolbox()->missionCommandTree()->friendlyName(queuedCommand.command))); qgcApp()->showMessage(tr("Vehicle did not respond to command: %1").arg(_toolbox->missionCommandTree()->friendlyName(queuedCommand.command)));
} }
_mavCommandQueue.removeFirst(); _mavCommandQueue.removeFirst();
_sendNextQueuedMavCommand(); _sendNextQueuedMavCommand();
@ -2614,6 +2628,30 @@ bool Vehicle::autoDisarm(void)
return false; return false;
} }
void Vehicle::_handleADSBVehicle(const mavlink_message_t& message)
{
mavlink_adsb_vehicle_t adsbVehicle;
static const int maxTimeSinceLastSeen = 15;
mavlink_msg_adsb_vehicle_decode(&message, &adsbVehicle);
if (adsbVehicle.flags | ADSB_FLAGS_VALID_COORDS) {
if (_adsbICAOMap.contains(adsbVehicle.ICAO_address)) {
if (adsbVehicle.tslc > maxTimeSinceLastSeen) {
ADSBVehicle* vehicle = _adsbICAOMap[adsbVehicle.ICAO_address];
_adsbVehicles.removeOne(vehicle);
_adsbICAOMap.remove(adsbVehicle.ICAO_address);
vehicle->deleteLater();
} else {
_adsbICAOMap[adsbVehicle.ICAO_address]->update(adsbVehicle);
}
} else if (adsbVehicle.tslc <= maxTimeSinceLastSeen) {
ADSBVehicle* vehicle = new ADSBVehicle(adsbVehicle, this);
_adsbICAOMap[adsbVehicle.ICAO_address] = vehicle;
_adsbVehicles.append(vehicle);
}
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

8
src/Vehicle/Vehicle.h

@ -38,6 +38,7 @@ class ParameterManager;
class JoystickManager; class JoystickManager;
class UASMessage; class UASMessage;
class SettingsManager; class SettingsManager;
class ADSBVehicle;
Q_DECLARE_LOGGING_CATEGORY(VehicleLog) Q_DECLARE_LOGGING_CATEGORY(VehicleLog)
@ -311,6 +312,7 @@ public:
Q_PROPERTY(int telemetryRNoise READ telemetryRNoise NOTIFY telemetryRNoiseChanged) Q_PROPERTY(int telemetryRNoise READ telemetryRNoise NOTIFY telemetryRNoiseChanged)
Q_PROPERTY(QVariantList toolBarIndicators READ toolBarIndicators CONSTANT) Q_PROPERTY(QVariantList toolBarIndicators READ toolBarIndicators CONSTANT)
Q_PROPERTY(QVariantList cameraList READ cameraList CONSTANT) Q_PROPERTY(QVariantList cameraList READ cameraList CONSTANT)
Q_PROPERTY(QmlObjectListModel* adsbVehicles READ adsbVehicles CONSTANT)
/// true: Vehicle is flying, false: Vehicle is on ground /// true: Vehicle is flying, false: Vehicle is on ground
Q_PROPERTY(bool flying READ flying NOTIFY flyingChanged) Q_PROPERTY(bool flying READ flying NOTIFY flyingChanged)
@ -527,6 +529,7 @@ public:
QmlObjectListModel* trajectoryPoints(void) { return &_mapTrajectoryList; } QmlObjectListModel* trajectoryPoints(void) { return &_mapTrajectoryList; }
QmlObjectListModel* cameraTriggerPoints(void) { return &_cameraTriggerPoints; } QmlObjectListModel* cameraTriggerPoints(void) { return &_cameraTriggerPoints; }
QmlObjectListModel* adsbVehicles(void) { return &_adsbVehicles; }
int flowImageIndex() { return _flowImageIndex; } int flowImageIndex() { return _flowImageIndex; }
@ -836,6 +839,7 @@ private:
void _handleScaledPressure3(mavlink_message_t& message); void _handleScaledPressure3(mavlink_message_t& message);
void _handleCameraFeedback(const mavlink_message_t& message); void _handleCameraFeedback(const mavlink_message_t& message);
void _handleCameraImageCaptured(const mavlink_message_t& message); void _handleCameraImageCaptured(const mavlink_message_t& message);
void _handleADSBVehicle(const mavlink_message_t& message);
void _missionManagerError(int errorCode, const QString& errorMsg); void _missionManagerError(int errorCode, const QString& errorMsg);
void _geoFenceManagerError(int errorCode, const QString& errorMsg); void _geoFenceManagerError(int errorCode, const QString& errorMsg);
void _rallyPointManagerError(int errorCode, const QString& errorMsg); void _rallyPointManagerError(int errorCode, const QString& errorMsg);
@ -866,6 +870,7 @@ private:
AutoPilotPlugin* _autopilotPlugin; AutoPilotPlugin* _autopilotPlugin;
MAVLinkProtocol* _mavlink; MAVLinkProtocol* _mavlink;
bool _soloFirmware; bool _soloFirmware;
QGCToolbox* _toolbox;
SettingsManager* _settingsManager; SettingsManager* _settingsManager;
QList<LinkInterface*> _links; QList<LinkInterface*> _links;
@ -974,6 +979,9 @@ private:
QmlObjectListModel _cameraTriggerPoints; QmlObjectListModel _cameraTriggerPoints;
QmlObjectListModel _adsbVehicles;
QMap<uint32_t, ADSBVehicle*> _adsbICAOMap;
// Toolbox references // Toolbox references
FirmwarePluginManager* _firmwarePluginManager; FirmwarePluginManager* _firmwarePluginManager;
JoystickManager* _joystickManager; JoystickManager* _joystickManager;

39
src/VehicleSetup/FirmwareUpgradeController.cc

@ -211,12 +211,7 @@ void FirmwareUpgradeController::_initFirmwareHash()
{ AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/px4fmu-v4_default.px4"}, { AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/px4fmu-v4_default.px4"},
{ AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/px4fmu-v4_default.px4"}, { AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/px4fmu-v4_default.px4"},
{ AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/px4fmu-v4_default.px4"}, { AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/px4fmu-v4_default.px4"},
{ AutoPilotStackAPM, StableFirmware, QuadFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-quad/ArduCopter-v4.px4"}, { AutoPilotStackAPM, StableFirmware, CopterFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4/ArduCopter-v4.px4"},
{ AutoPilotStackAPM, StableFirmware, X8Firmware, "http://firmware.ardupilot.org/Copter/stable/PX4-octa-quad/ArduCopter-v4.px4"},
{ AutoPilotStackAPM, StableFirmware, HexaFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-hexa/ArduCopter-v4.px4"},
{ AutoPilotStackAPM, StableFirmware, OctoFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-octa/ArduCopter-v4.px4"},
{ AutoPilotStackAPM, StableFirmware, YFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-tri/ArduCopter-v4.px4"},
{ AutoPilotStackAPM, StableFirmware, Y6Firmware, "http://firmware.ardupilot.org/Copter/stable/PX4-y6/ArduCopter-v4.px4"},
{ AutoPilotStackAPM, StableFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-heli/ArduCopter-v4.px4"}, { AutoPilotStackAPM, StableFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-heli/ArduCopter-v4.px4"},
{ AutoPilotStackAPM, StableFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/stable/PX4/ArduPlane-v4.px4"}, { AutoPilotStackAPM, StableFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/stable/PX4/ArduPlane-v4.px4"},
{ AutoPilotStackAPM, StableFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/stable/PX4/APMrover2-v4.px4"}, { AutoPilotStackAPM, StableFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/stable/PX4/APMrover2-v4.px4"},
@ -232,18 +227,12 @@ void FirmwareUpgradeController::_initFirmwareHash()
}; };
//////////////////////////////////// PX4FMUV3 firmwares ////////////////////////////////////////////////// //////////////////////////////////// PX4FMUV3 firmwares //////////////////////////////////////////////////
// Note: ArduPilot stable does not yet support V3 firmwares, so fall back to V2
FirmwareToUrlElement_t rgPX4FMV3FirmwareArray[] = { FirmwareToUrlElement_t rgPX4FMV3FirmwareArray[] = {
{ AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/px4fmu-v3_default.px4"}, { AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/px4fmu-v3_default.px4"},
{ AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/px4fmu-v3_default.px4"}, { AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/px4fmu-v3_default.px4"},
{ AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/px4fmu-v3_default.px4"}, { AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/px4fmu-v3_default.px4"},
{ AutoPilotStackAPM, StableFirmware, QuadFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-quad/ArduCopter-v2.px4"}, { AutoPilotStackAPM, StableFirmware, CopterFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4/ArduCopter-v3.px4"},
{ AutoPilotStackAPM, StableFirmware, X8Firmware, "http://firmware.ardupilot.org/Copter/stable/PX4-octa-quad/ArduCopter-v2.px4"}, { AutoPilotStackAPM, StableFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-heli/ArduCopter-v3.px4"},
{ AutoPilotStackAPM, StableFirmware, HexaFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-hexa/ArduCopter-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, OctoFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-octa/ArduCopter-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, YFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-tri/ArduCopter-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, Y6Firmware, "http://firmware.ardupilot.org/Copter/stable/PX4-y6/ArduCopter-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-heli/ArduCopter-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/stable/PX4/ArduPlane-v2.px4"}, { AutoPilotStackAPM, StableFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/stable/PX4/ArduPlane-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/stable/PX4/APMrover2-v2.px4"}, { AutoPilotStackAPM, StableFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/stable/PX4/APMrover2-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, SubFirmware, "http://firmware.ardupilot.org/Sub/stable/PX4/ArduSub-v2.px4"}, { AutoPilotStackAPM, StableFirmware, SubFirmware, "http://firmware.ardupilot.org/Sub/stable/PX4/ArduSub-v2.px4"},
@ -265,12 +254,7 @@ void FirmwareUpgradeController::_initFirmwareHash()
{ AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/px4fmu-v2_default.px4"}, { AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/px4fmu-v2_default.px4"},
{ AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/px4fmu-v2_default.px4"}, { AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/px4fmu-v2_default.px4"},
{ AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/px4fmu-v2_default.px4"}, { AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/px4fmu-v2_default.px4"},
{ AutoPilotStackAPM, StableFirmware, QuadFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-quad/ArduCopter-v2.px4"}, { AutoPilotStackAPM, StableFirmware, CopterFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4/ArduCopter-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, X8Firmware, "http://firmware.ardupilot.org/Copter/stable/PX4-octa-quad/ArduCopter-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, HexaFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-hexa/ArduCopter-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, OctoFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-octa/ArduCopter-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, YFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-tri/ArduCopter-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, Y6Firmware, "http://firmware.ardupilot.org/Copter/stable/PX4-y6/ArduCopter-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-heli/ArduCopter-v2.px4"}, { AutoPilotStackAPM, StableFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-heli/ArduCopter-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/stable/PX4/ArduPlane-v2.px4"}, { AutoPilotStackAPM, StableFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/stable/PX4/ArduPlane-v2.px4"},
{ AutoPilotStackAPM, StableFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/stable/PX4/APMrover2-v2.px4"}, { AutoPilotStackAPM, StableFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/stable/PX4/APMrover2-v2.px4"},
@ -322,12 +306,7 @@ void FirmwareUpgradeController::_initFirmwareHash()
{ AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/px4fmu-v1_default.px4"}, { AutoPilotStackPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/stable/px4fmu-v1_default.px4"},
{ AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/px4fmu-v1_default.px4"}, { AutoPilotStackPX4, BetaFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/beta/px4fmu-v1_default.px4"},
{ AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/px4fmu-v1_default.px4"}, { AutoPilotStackPX4, DeveloperFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Firmware/master/px4fmu-v1_default.px4"},
{ AutoPilotStackAPM, StableFirmware, QuadFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-quad/ArduCopter-v1.px4"}, { AutoPilotStackAPM, StableFirmware, CopterFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4/ArduCopter-v1.px4"},
{ AutoPilotStackAPM, StableFirmware, X8Firmware, "http://firmware.ardupilot.org/Copter/stable/PX4-octa-quad/ArduCopter-v1.px4"},
{ AutoPilotStackAPM, StableFirmware, HexaFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-hexa/ArduCopter-v1.px4"},
{ AutoPilotStackAPM, StableFirmware, OctoFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-octa/ArduCopter-v1.px4"},
{ AutoPilotStackAPM, StableFirmware, YFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-tri/ArduCopter-v1.px4"},
{ AutoPilotStackAPM, StableFirmware, Y6Firmware, "http://firmware.ardupilot.org/Copter/stable/PX4-y6/ArduCopter-v1.px4"},
{ AutoPilotStackAPM, StableFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-heli/ArduCopter-v1.px4"}, { AutoPilotStackAPM, StableFirmware, HeliFirmware, "http://firmware.ardupilot.org/Copter/stable/PX4-heli/ArduCopter-v1.px4"},
{ AutoPilotStackAPM, StableFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/stable/PX4/ArduPlane-v1.px4"}, { AutoPilotStackAPM, StableFirmware, PlaneFirmware, "http://firmware.ardupilot.org/Plane/stable/PX4/ArduPlane-v1.px4"},
{ AutoPilotStackAPM, StableFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/stable/PX4/APMrover2-v1.px4"}, { AutoPilotStackAPM, StableFirmware, RoverFirmware, "http://firmware.ardupilot.org/Rover/stable/PX4/APMrover2-v1.px4"},
@ -775,10 +754,15 @@ void FirmwareUpgradeController::setSelectedFirmwareType(FirmwareType_t firmwareT
QStringList FirmwareUpgradeController::apmAvailableVersions(void) QStringList FirmwareUpgradeController::apmAvailableVersions(void)
{ {
QStringList list; QStringList list;
QList<FirmwareVehicleType_t> vehicleTypes;
// This allows up to force the order of the combo box display
vehicleTypes << CopterFirmware << HeliFirmware << PlaneFirmware << RoverFirmware << SubFirmware;
_apmVehicleTypeFromCurrentVersionList.clear(); _apmVehicleTypeFromCurrentVersionList.clear();
foreach (FirmwareVehicleType_t vehicleType, _apmVersionMap[_selectedFirmwareType].keys()) { foreach (FirmwareVehicleType_t vehicleType, vehicleTypes) {
if (_apmVersionMap[_selectedFirmwareType].contains(vehicleType)) {
QString version; QString version;
switch (vehicleType) { switch (vehicleType) {
@ -820,6 +804,7 @@ QStringList FirmwareUpgradeController::apmAvailableVersions(void)
list << version; list << version;
} }
}
return list; return list;
} }

16
src/api/QGCCorePlugin.cc

@ -176,6 +176,13 @@ bool QGCCorePlugin::adjustSettingMetaData(FactMetaData& metaData)
metaData.setRawDefaultValue(true); metaData.setRawDefaultValue(true);
return true; return true;
#endif #endif
#if defined(__ios__)
} else if (metaData.name() == AppSettings::savePathName) {
QString appName = qgcApp()->applicationName();
QDir rootDir = QDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
metaData.setRawDefaultValue(rootDir.filePath(appName));
return false;
#endif
} }
return true; // Show setting in ui return true; // Show setting in ui
} }
@ -225,3 +232,12 @@ QQmlApplicationEngine* QGCCorePlugin::createRootWindow(QObject *parent)
pEngine->load(QUrl(QStringLiteral("qrc:/qml/MainWindowNative.qml"))); pEngine->load(QUrl(QStringLiteral("qrc:/qml/MainWindowNative.qml")));
return pEngine; return pEngine;
} }
bool QGCCorePlugin::mavlinkMessage(Vehicle* vehicle, LinkInterface* link, mavlink_message_t message)
{
Q_UNUSED(vehicle);
Q_UNUSED(link);
Q_UNUSED(message);
return true;
}

7
src/api/QGCCorePlugin.h

@ -11,6 +11,7 @@
#include "QGCToolbox.h" #include "QGCToolbox.h"
#include "QGCPalette.h" #include "QGCPalette.h"
#include "QGCMAVLink.h"
#include <QObject> #include <QObject>
#include <QVariantList> #include <QVariantList>
@ -28,6 +29,8 @@ class QGCCorePlugin_p;
class FactMetaData; class FactMetaData;
class QGeoPositionInfoSource; class QGeoPositionInfoSource;
class QQmlApplicationEngine; class QQmlApplicationEngine;
class Vehicle;
class LinkInterface;
class QGCCorePlugin : public QGCTool class QGCCorePlugin : public QGCTool
{ {
@ -90,6 +93,10 @@ public:
/// Allows the plugin to override the creation of the root (native) window. /// Allows the plugin to override the creation of the root (native) window.
virtual QQmlApplicationEngine* createRootWindow(QObject* parent); virtual QQmlApplicationEngine* createRootWindow(QObject* parent);
/// Allows the plugin to see all mavlink traffic to a vehicle
/// @return true: Allow vehicle to continue processing, false: Vehicle should not process message
virtual bool mavlinkMessage(Vehicle* vehicle, LinkInterface* link, mavlink_message_t message);
bool showTouchAreas(void) const { return _showTouchAreas; } bool showTouchAreas(void) const { return _showTouchAreas; }
bool showAdvancedUI(void) const { return _showAdvancedUI; } bool showAdvancedUI(void) const { return _showAdvancedUI; }
void setShowTouchAreas(bool show); void setShowTouchAreas(bool show);

35
src/comm/MockLink.cc

@ -33,9 +33,11 @@ QGC_LOGGING_CATEGORY(MockLinkVerboseLog, "MockLinkVerboseLog")
/// ///
/// @author Don Gagne <don@thegagnes.com> /// @author Don Gagne <don@thegagnes.com>
float MockLink::_vehicleLatitude = 47.633033f; // Vehicle position is set close to default Gazebo vehicle location. This allows for multi-vehicle
float MockLink::_vehicleLongitude = -122.08794f; // testing of a gazebo vehicle and a mocklink vehicle
float MockLink::_vehicleAltitude = 3.5f; double MockLink::_defaultVehicleLatitude = 47.397f;
double MockLink::_defaultVehicleLongitude = 8.5455f;
double MockLink::_defaultVehicleAltitude = 488.056f;
int MockLink::_nextVehicleSystemId = 128; int MockLink::_nextVehicleSystemId = 128;
const char* MockLink::_failParam = "COM_FLTMODE6"; const char* MockLink::_failParam = "COM_FLTMODE6";
@ -58,6 +60,9 @@ MockLink::MockLink(SharedLinkConfigurationPointer& config)
, _mavState (MAV_STATE_STANDBY) , _mavState (MAV_STATE_STANDBY)
, _firmwareType (MAV_AUTOPILOT_PX4) , _firmwareType (MAV_AUTOPILOT_PX4)
, _vehicleType (MAV_TYPE_QUADROTOR) , _vehicleType (MAV_TYPE_QUADROTOR)
, _vehicleLatitude (_defaultVehicleLatitude + ((_vehicleSystemId - 128) * 0.0001)) // Slight offset for each vehicle
, _vehicleLongitude (_defaultVehicleLongitude + ((_vehicleSystemId - 128) * 0.0001))
, _vehicleAltitude (_defaultVehicleAltitude)
, _fileServer (NULL) , _fileServer (NULL)
, _sendStatusText (false) , _sendStatusText (false)
, _apmSendHomePositionOnEmptyList (false) , _apmSendHomePositionOnEmptyList (false)
@ -156,6 +161,7 @@ void MockLink::_run1HzTasks(void)
{ {
if (_mavlinkStarted && _connected) { if (_mavlinkStarted && _connected) {
_sendVibration(); _sendVibration();
_sendADSBVehicles();
if (!qgcApp()->runningUnitTests()) { if (!qgcApp()->runningUnitTests()) {
// Sending RC Channels during unit test breaks RC tests which does it's own RC simulation // Sending RC Channels during unit test breaks RC tests which does it's own RC simulation
_sendRCChannels(); _sendRCChannels();
@ -1263,3 +1269,26 @@ void MockLink::_logDownloadWorker(void)
} }
} }
} }
void MockLink::_sendADSBVehicles(void)
{
mavlink_message_t responseMsg;
mavlink_msg_adsb_vehicle_pack_chan(_vehicleSystemId,
_vehicleComponentId,
_mavlinkChannel,
&responseMsg,
12345, // ICAO address
(_vehicleLatitude + 0.001) * 1e7,
(_vehicleLongitude + 0.001) * 1e7,
ADSB_ALTITUDE_TYPE_GEOMETRIC,
100 * 1000, // Altitude in millimeters
10 * 100, // Heading in centidegress
0, 0, // Horizontal/Vertical velocity
"N1234500", // Callsign
ADSB_EMITTER_TYPE_ROTOCRAFT,
1, // Seconds since last communication
ADSB_FLAGS_VALID_COORDS | ADSB_FLAGS_VALID_ALTITUDE | ADSB_FLAGS_VALID_HEADING | ADSB_FLAGS_VALID_CALLSIGN | ADSB_FLAGS_SIMULATED,
0); // Squawk code
respondWithMavlinkMessage(responseMsg);
}

10
src/comm/MockLink.h

@ -192,6 +192,7 @@ private:
void _sendRCChannels(void); void _sendRCChannels(void);
void _paramRequestListWorker(void); void _paramRequestListWorker(void);
void _logDownloadWorker(void); void _logDownloadWorker(void);
void _sendADSBVehicles(void);
static MockLink* _startMockLink(MockConfiguration* mockConfig); static MockLink* _startMockLink(MockConfiguration* mockConfig);
@ -216,6 +217,9 @@ private:
MAV_AUTOPILOT _firmwareType; MAV_AUTOPILOT _firmwareType;
MAV_TYPE _vehicleType; MAV_TYPE _vehicleType;
double _vehicleLatitude;
double _vehicleLongitude;
double _vehicleAltitude;
MockLinkFileServer* _fileServer; MockLinkFileServer* _fileServer;
@ -236,9 +240,9 @@ private:
uint32_t _logDownloadCurrentOffset; ///< Current offset we are sending from uint32_t _logDownloadCurrentOffset; ///< Current offset we are sending from
uint32_t _logDownloadBytesRemaining; ///< Number of bytes still to send, 0 = send inactive uint32_t _logDownloadBytesRemaining; ///< Number of bytes still to send, 0 = send inactive
static float _vehicleLatitude; static double _defaultVehicleLatitude;
static float _vehicleLongitude; static double _defaultVehicleLongitude;
static float _vehicleAltitude; static double _defaultVehicleAltitude;
static int _nextVehicleSystemId; static int _nextVehicleSystemId;
static const char* _failParam; static const char* _failParam;
}; };

4
src/qgcunittest/UnitTestList.cc

@ -52,6 +52,7 @@ UT_REGISTER_TEST(MissionControllerTest)
UT_REGISTER_TEST(MissionManagerTest) UT_REGISTER_TEST(MissionManagerTest)
UT_REGISTER_TEST(RadioConfigTest) UT_REGISTER_TEST(RadioConfigTest)
UT_REGISTER_TEST(TCPLinkTest) UT_REGISTER_TEST(TCPLinkTest)
UT_REGISTER_TEST(FileManagerTest)
UT_REGISTER_TEST(ParameterManagerTest) UT_REGISTER_TEST(ParameterManagerTest)
UT_REGISTER_TEST(MissionCommandTreeTest) UT_REGISTER_TEST(MissionCommandTreeTest)
UT_REGISTER_TEST(LogDownloadTest) UT_REGISTER_TEST(LogDownloadTest)
@ -69,8 +70,5 @@ UT_REGISTER_TEST(QGCMapPolygonTest)
// FIXME: Temporarily disabled until this can be stabilized // FIXME: Temporarily disabled until this can be stabilized
//UT_REGISTER_TEST(MainWindowTest) //UT_REGISTER_TEST(MainWindowTest)
// Onboard file support has been removed until it can be make to work correctly
//UT_REGISTER_TEST(FileManagerTest)
// Needs to be update for latest updates // Needs to be update for latest updates
//UT_REGISTER_TEST(MavlinkLogTest) //UT_REGISTER_TEST(MavlinkLogTest)

1
src/uas/FileManager.cc

@ -239,6 +239,7 @@ void FileManager::_writeAckResponse(Request* writeAck)
{ {
if(_writeOffset + _writeSize >= _writeFileSize){ if(_writeOffset + _writeSize >= _writeFileSize){
_closeUploadSession(true /* success */); _closeUploadSession(true /* success */);
return;
} }
if (writeAck->hdr.session != _activeSession) { if (writeAck->hdr.session != _activeSession) {

11
src/ui/MainWindow.cc

@ -296,7 +296,7 @@ QString MainWindow::_getWindowGeometryKey()
#ifndef __mobile__ #ifndef __mobile__
MAVLinkDecoder* MainWindow::_mavLinkDecoderInstance(void) MAVLinkDecoder* MainWindow::_mavLinkDecoderInstance(void)
{ {
if (_mavlinkDecoder) { if (!_mavlinkDecoder) {
_mavlinkDecoder = new MAVLinkDecoder(qgcApp()->toolbox()->mavlinkProtocol()); _mavlinkDecoder = new MAVLinkDecoder(qgcApp()->toolbox()->mavlinkProtocol());
connect(_mavlinkDecoder, &MAVLinkDecoder::valueChanged, this, &MainWindow::valueChanged); connect(_mavlinkDecoder, &MAVLinkDecoder::valueChanged, this, &MainWindow::valueChanged);
} }
@ -313,10 +313,6 @@ void MainWindow::_buildCommonWidgets(void)
// Populate widget menu // Populate widget menu
for (int i = 0, end = ARRAY_SIZE(rgDockWidgetNames); i < end; i++) { for (int i = 0, end = ARRAY_SIZE(rgDockWidgetNames); i < end; i++) {
if (i == ONBOARD_FILES) {
// Temporarily removed until twe can fix all the problems with it
continue;
}
const char* pDockWidgetName = rgDockWidgetNames[i]; const char* pDockWidgetName = rgDockWidgetNames[i];
@ -333,11 +329,6 @@ void MainWindow::_buildCommonWidgets(void)
/// Shows or hides the specified dock widget, creating if necessary /// Shows or hides the specified dock widget, creating if necessary
void MainWindow::_showDockWidget(const QString& name, bool show) void MainWindow::_showDockWidget(const QString& name, bool show)
{ {
if (name == rgDockWidgetNames[ONBOARD_FILES]) {
// Temporarily disabled due to bugs
return;
}
// Create the inner widget if we need to // Create the inner widget if we need to
if (!_mapName2DockWidget.contains(name)) { if (!_mapName2DockWidget.contains(name)) {
if(!_createInnerDockWidget(name)) { if(!_createInnerDockWidget(name)) {

2
src/ui/QGCUASFileView.cc

@ -198,7 +198,7 @@ void QGCUASFileView::_commandComplete(void)
_currentCommand = commandNone; _currentCommand = commandNone;
_setAllButtonsEnabled(true); _setAllButtonsEnabled(true);
statusText = "Download complete"; statusText = "Download complete";
} else if (_currentCommand == commandDownload) { } else if (_currentCommand == commandUpload) {
_currentCommand = commandNone; _currentCommand = commandNone;
_setAllButtonsEnabled(true); _setAllButtonsEnabled(true);
statusText = "Upload complete"; statusText = "Upload complete";

Loading…
Cancel
Save