Commit 1d7cf605 authored by Gus Grubba's avatar Gus Grubba

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

# Conflicts:
#	qgcresources.qrc
#	src/FlightDisplay/FlightDisplayView.qml
#	src/MissionManager/MissionController.cc
#	src/MissionManager/SurveyMissionItem.cc
#	src/MissionManager/SurveyMissionItem.h
#	src/PlanView/PlanView.qml
#	src/QGCApplication.cc
#	src/Settings/AppSettings.h
#	src/Vehicle/Vehicle.h

Note that SurveyMissionItem (.h/.cc) was changed in such a way that all previous changes were lost. Dynamic computation of its bounding box is missing and needs to be added into whatever is now handling these.
parents 661eeff7 0801e473
......@@ -15,7 +15,7 @@ environment:
install:
- git submodule update --init --recursive
- call "%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86
- set PATH=C:\Qt\Tools\QtCreator\bin;C:\Qt\5.9.4\msvc2015\bin;%PATH%
- set PATH=C:\Qt\Tools\QtCreator\bin;C:\Qt\5.9.5\msvc2015\bin;%PATH%
- mkdir %LOCALAPPDATA%\QtProject && copy test\qtlogging.ini %LOCALAPPDATA%\QtProject\
- ps: |
Write-Host "Installing GStreamer..." -ForegroundColor Cyan
......@@ -35,7 +35,7 @@ install:
Write-Host "Installed" -ForegroundColor Green
build_script:
- mkdir %SHADOW_BUILD_DIR% && cd %SHADOW_BUILD_DIR% && C:\Qt\5.9.4\msvc2015\bin\qmake -r CONFIG-=debug_and_release CONFIG+=%CONFIG% CONFIG+=WarningsAsErrorsOn %APPVEYOR_BUILD_FOLDER%\qgroundcontrol.pro
- mkdir %SHADOW_BUILD_DIR% && cd %SHADOW_BUILD_DIR% && C:\Qt\5.9.5\msvc2015\bin\qmake -r CONFIG-=debug_and_release CONFIG+=%CONFIG% CONFIG+=WarningsAsErrorsOn %APPVEYOR_BUILD_FOLDER%\qgroundcontrol.pro
- cd %SHADOW_BUILD_DIR% && jom
- if "%CONFIG%" EQU "installer" ( copy %SHADOW_BUILD_DIR%\release\QGroundControl-installer.exe %APPVEYOR_BUILD_FOLDER%\QGroundControl-installer.exe )
# Generate the source server information to embed in the PDB
......
......@@ -73,9 +73,9 @@ before_install:
install:
# linux dependencies: qt
- if [ "${SPEC}" = "linux-g++-64" ]; then
wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.9.3-gcc_64-min.tar.bz2 &&
tar jxf Qt5.9.3-gcc_64-min.tar.bz2 -C /tmp &&
export PATH=/tmp/Qt5.9-gcc_64/5.9.3/gcc_64/bin:$PATH &&
wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.11.0-gcc_64-min.tar.bz2 &&
tar jxf Qt5.11.0-gcc_64-min.tar.bz2 -C /tmp &&
export PATH=/tmp/Qt5.11-gcc_64/5.11.0/gcc_64/bin:$PATH &&
export DISPLAY=:99.0 &&
sh -e /etc/init.d/xvfb start
;
......@@ -83,8 +83,8 @@ install:
# android dependencies: qt, gstreamer, android-ndk
- if [ "${SPEC}" = "android-g++" ]; then
wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.9.3-android_armv7-min.tar.bz2 &&
tar jxf Qt5.9.3-android_armv7-min.tar.bz2 -C /tmp &&
wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.11.0-android_armv7-min.tar.bz2 &&
tar jxf Qt5.11.0-android_armv7-min.tar.bz2 -C /tmp &&
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 &&
tar jxf gstreamer-1.0-android-armv7-1.5.2.tar.bz2 -C ${TRAVIS_BUILD_DIR}/gstreamer-1.0-android-armv7-1.5.2 &&
......@@ -93,14 +93,14 @@ install:
./android-ndk-r10e-linux-x86_64.bin > /dev/null &&
export ANDROID_NDK_ROOT=`pwd`/android-ndk-r10e &&
export ANDROID_SDK_ROOT=/usr/local/android-sdk &&
export PATH=/tmp/Qt5.9-android_armv7/5.9.3/android_armv7/bin:`pwd`/android-ndk-r10e:$PATH && echo $PATH
export PATH=/tmp/Qt5.11-android_armv7/5.11.0/android_armv7/bin:`pwd`/android-ndk-r10e:$PATH && echo $PATH
;
fi
# osx dependencies: qt (master builds only: gstreamer, gstreamer-devel)
- if [ "${SPEC}" = "macx-clang" ]; then
wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.9.3-clang_64-min.tar.bz2 &&
tar jxf Qt5.9.3-clang_64-min.tar.bz2 -C /tmp
wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.11.0-clang_64-min.tar.bz2 &&
tar jxf Qt5.11.0-clang_64-min.tar.bz2 -C /tmp
;
fi
......@@ -123,7 +123,7 @@ install:
fi
- if [ "${SPEC}" = "macx-clang" ]; then
export QT_DIR=Qt5.9-clang_64/5.9.3/clang_64 &&
export QT_DIR=Qt5.11-clang_64/5.11.0/clang_64 &&
export QT_QPA_PLATFORM_PLUGIN_PATH=/tmp/$QT_DIR/plugins &&
export QML2_IMPORT_PATH=/tmp/$QT_DIR/qml &&
export PATH=/tmp/$QT_DIR/bin:$PATH
......@@ -161,7 +161,12 @@ before_script:
script:
# run qmake
- mkdir ${SHADOW_BUILD_DIR} && cd ${SHADOW_BUILD_DIR}
- qmake -r ${TRAVIS_BUILD_DIR}/qgroundcontrol.pro CONFIG+=${CONFIG} CONFIG+=WarningsAsErrorsOn -spec ${SPEC}
# Due to possible bug in Qt 5.11 WarningsAsErrorsOn is off for Linux builds. Hopefully back on once that is resolved.
- if [ "${SPEC}" = "macx-clang" ]; then
qmake -r ${TRAVIS_BUILD_DIR}/qgroundcontrol.pro CONFIG+=${CONFIG} CONFIG+=WarningsAsErrorsOn -spec ${SPEC};
else
qmake -r ${TRAVIS_BUILD_DIR}/qgroundcontrol.pro CONFIG+=${CONFIG} -spec ${SPEC};
fi
# compile
- if [ "${SPEC}" != "macx-ios-clang" ]; then
......
configs:
dev:
'qt_deps_tarball': 'Qt5.9.1-linux-vagrant.tar.bz2'
'qt_deps_tarball': 'Qt5.11.0-gcc_64-min.tar.bz2'
'qt_deps_unpack_parent_dir': '/tmp'
'qt_deps_unpack_dir': '/tmp/Qt5.9-vagrant/5.9.1'
'qt_deps_bin_unpack_dir': '/tmp/Qt5.9-vagrant/5.9.1/gcc_64/bin'
'qt_deps_lib_unpack_dir': '/tmp/Qt5.9-vagrant/5.9.1/gcc_64/lib'
'qt_deps_plugins_unpack_dir': '/tmp/Qt5.9-vagrant/5.9.1/gcc_64/plugins'
'qt_deps_qml_unpack_dir': '/tmp/Qt5.9-vagrant/5.9.1/gcc_64/qml'
'qt_deps_unpack_dir': '/tmp/Qt5.11-gcc_64/5.11.0'
'qt_deps_bin_unpack_dir': '/tmp/Qt5.11-gcc_64/5.11.0/gcc_64/bin'
'qt_deps_lib_unpack_dir': '/tmp/Qt5.11-gcc_64/5.11.0/gcc_64/lib'
'qt_deps_plugins_unpack_dir': '/tmp/Qt5.11-gcc_64/5.11.0/gcc_64/plugins'
'qt_deps_qml_unpack_dir': '/tmp/Qt5.11-gcc_64/5.11.0/gcc_64/qml'
'project_root_dir': '/vagrant'
......@@ -20,4 +20,4 @@ configs:
'spec': 'linux-g++-64'
'shadow_build_dir': '/vagrant/shadow-build'
'pro': '/vagrant/qgroundcontrol.pro'
'deps_url': 'https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.9.1-linux-vagrant.tar.bz2'
'deps_url': 'https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.11.0-gcc_64-min.tar.bz2'
......@@ -4,6 +4,7 @@ This system is for posting bugs or feature requests ONLY. For questions about ho
When posting bug reports, include the following informaiton:
- Ground station operating system.
- QGroundControl version and build (daily, stable, self-built from source, etc.)
- **If you are using a Stable build which is not the latest, first step is to install latest Stable build and try again prior to entering a bug report.**
- Autopilot board: Pixhawk I, Pixhawk Mini, Pixhawk 2, etc.
- Autopilot firmware (e.g. PX4, ArduPilot, custom) and version.
- Exact steps to reproduce the problem. Starting from booting QGroundControl to when the problem occurs.
......
pipeline {
agent any
agent none
stages {
stage('build') {
parallel {
stage('Android Release') {
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
QGC_CONFIG = 'release'
QMAKE_VER = "5.9.2/android_armv7/bin/qmake"
}
agent {
docker {
image 'mavlink/qgc-build-android:2018-04-14'
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`'
sh 'ccache -s'
}
post {
cleanup {
sh 'git clean -ff -x -d .'
}
}
}
stage('Linux Debug') {
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
......@@ -11,7 +42,7 @@ pipeline {
}
agent {
docker {
image 'mavlink/qgc-build-linux'
image 'mavlink/qgc-build-linux:2018-04-14'
args '-v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
......@@ -25,7 +56,13 @@ pipeline {
sh 'cd build; make -j`nproc --all`'
sh 'ccache -s'
}
post {
cleanup {
sh 'git clean -ff -x -d .'
}
}
}
stage('Linux Release') {
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
......@@ -34,7 +71,7 @@ pipeline {
}
agent {
docker {
image 'mavlink/qgc-build-linux'
image 'mavlink/qgc-build-linux:2018-04-14'
args '-v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
......@@ -48,7 +85,13 @@ pipeline {
sh 'cd build; make -j`nproc --all`'
sh 'ccache -s'
}
post {
cleanup {
sh 'git clean -ff -x -d .'
}
}
}
stage('OSX Debug') {
agent {
node {
......@@ -70,7 +113,13 @@ pipeline {
sh 'cd build; make -j`sysctl -n hw.ncpu`'
sh 'ccache -s'
}
post {
cleanup {
sh 'git clean -ff -x -d .'
}
}
}
stage('OSX Release') {
agent {
node {
......@@ -79,7 +128,7 @@ pipeline {
}
environment {
CCACHE_BASEDIR = "${env.WORKSPACE}"
QGC_CONFIG = 'release'
QGC_CONFIG = 'installer'
QMAKE_VER = "5.9.3/clang_64/bin/qmake"
}
steps {
......@@ -92,13 +141,27 @@ pipeline {
sh 'cd build; make -j`sysctl -n hw.ncpu`'
sh 'ccache -s'
}
post {
success {
archiveArtifacts(artifacts: 'build/**/*.dmg', fingerprint: true)
}
cleanup {
sh 'git clean -ff -x -d .'
}
}
}
}
}
}
} // parallel
} // stage('build')
} // stages
environment {
CCACHE_CPP2 = '1'
CCACHE_DIR = '/tmp/ccache'
QT_FATAL_WARNINGS = '1'
}
options {
buildDiscarder(logRotator(numToKeepStr: '10', artifactDaysToKeepStr: '30'))
timeout(time: 60, unit: 'MINUTES')
}
}
......@@ -68,7 +68,9 @@ WindowsBuild {
ReleaseBuild: DLL_QT_DEBUGCHAR = ""
COPY_FILE_LIST = \
$$BASEDIR\\libs\\lib\\sdl2\\msvc\\lib\\x86\\SDL2.dll \
$$BASEDIR\\deploy\\libeay32.dll
$$BASEDIR\\deploy\\libeay32.dll \
$$BASEDIR_WIN\\deploy\\libssl32.dll \
$$BASEDIR_WIN\\deploy\\ssleay32.dll
for(COPY_FILE, COPY_FILE_LIST) {
QMAKE_POST_LINK += $$escape_expand(\\n) $$QMAKE_COPY \"$$COPY_FILE\" \"$$DESTDIR_WIN\"
......@@ -107,15 +109,17 @@ LinuxBuild {
# QT_INSTALL_LIBS
QT_LIB_LIST = \
libQt5Charts.so.5 \
libQt5Core.so.5 \
libQt5DBus.so.5 \
libQt5Gui.so.5 \
libQt5Location.so.5 \
libQt5Multimedia.so.5 \
libQt5MultimediaQuick_p.so.5 \
libQt5MultimediaQuick.so.5 \
libQt5Network.so.5 \
libQt5OpenGL.so.5 \
libQt5Positioning.so.5 \
libQt5PositioningQuick.so.5 \
libQt5PrintSupport.so.5 \
libQt5Qml.so.5 \
libQt5Quick.so.5 \
......
......@@ -6,83 +6,20 @@
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mavlink/qgroundcontrol?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Website: <http://qgroundcontrol.com>
## Obtaining source code
*QGroundControl* (QGC) is an intuitive and powerful ground control station (GCS) for UAVs.
Source code for QGroundControl is kept on GitHub: https://github.com/mavlink/qgroundcontrol.
```
git clone --recursive https://github.com/mavlink/qgroundcontrol.git
```
Each time you pull new source to your repository you should run `git submodule update` to get the latest submodules as well. Since QGroundControl uses submodules, using the zip file for source download will not work. You must use git.
The primary goal of QGC is ease of use for both first time and professional users.
It provides full flight control and mission planning for any MAVLink enabled drone, and vehicle setup for both PX4 and ArduPilot powered UAVs. Instructions for *using QGroundControl* are provided in the [User Manual](https://docs.qgroundcontrol.com/en/) (you may not need them because the UI is very intuitive!)
The source code is [dual-licensed under Apache 2.0 and GPLv3](https://github.com/mavlink/qgroundcontrol/blob/master/COPYING.md).
All the code is open-source, so you can contribute and evolve it as you want.
The [Developer Guide](https://dev.qgroundcontrol.com/en/) explains how to [build](https://dev.qgroundcontrol.com/en/getting_started/) and extend QGC.
### User Manual
https://docs.qgroundcontrol.com/en/
### Supported Builds
#### Native Builds
QGroundControl builds are supported for OSX, Linux, Windows, iOS and Android. QGroundControl uses [Qt](http://www.qt.io) as its cross-platform support library and uses [QtCreator](http://doc.qt.io/qtcreator/index.html) as its default build environment.
* OSX: OSX 10.7 or higher, 64 bit, clang compiler (IMPORTANT: XCode 8 requires a workaround described below)
* Ubuntu: 64 bit, gcc compiler
* Windows: Vista or higher, 32 bit, [Visual Studio 2015 compiler](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop)
* iOS: 8.0 and higher
* Android: Jelly Bean (4.1) and higher. Standard QGC is built against ndk version 19.
* Qt version: **5.9.3 only**
###### Install QT
You **need to install Qt as described below** instead of using pre-built packages from say, a Linux distribution, because QGroundControl needs access to private Qt headers.
* Download the [Qt installer](http://www.qt.io/download-open-source)
* Make sure to install Qt version **5.9.3**. You will also need to install the Qt Speech package.
* Ubuntu: Set the downloaded file to executable using:`chmod +x`. Install to default location for use with ./qgroundcontrol-start.sh. If you install Qt to a non-default location you will need to modify qgroundcontrol-start.sh in order to run downloaded builds.
* Windows: Make sure to install VS 2015 32 bit package.
###### Install additional packages:
* Ubuntu: sudo apt-get install speech-dispatcher libudev-dev libsdl2-dev
* Fedora: sudo dnf install speech-dispatcher SDL2-devel SDL2 systemd-devel
* Arch Linux: pacman -Sy speech-dispatcher
* Windows: [USB Driver](http://www.pixhawk.org/firmware/downloads) to connect to Pixhawk/PX4Flow/3DR Radio
* Android: [Qt Android Setup](http://doc.qt.io/qt-5/androidgs.html)
###### Building using Qt Creator
* Launch Qt Creator and open the `qgroundcontrol.pro` project.
* Select the appropriate kit for your needs:
* OSX: Desktop Qt 5.9.3 clang 64 bit
* Ubuntu: Desktop Qt 5.9.3 GCC bit
* Windows: Desktop Qt 5.9.3 MSVC2015 32bit
* Android: Android for armeabi-v7a (GCC 4.9, Qt 5.9.3)
* Note: iOS builds must be built using xCode: http://doc.qt.io/qt-5/ios-support.html. Use Qt Creator to generate the XCode project (*Run Qmake* from the context menu).
#### Vagrant
A Vagrantfile is provided to build QGroundControl using the [Vagrant](https://www.vagrantup.com/) system. This will produce a native Linux build which can be run in the Vagrant Virtual Machine or on the host machine if it is compatible.
* [Download](https://www.vagrantup.com/downloads.html) Vagrant
* [Install](https://www.vagrantup.com/docs/getting-started/) Vagrant
* From the root directory of the QGroundControl repository run "vagrant up"
* To use the graphical environment run "vagrant reload"
#### Additional build notes for all supported OS
* Warnings as Errors: Specifying `CONFIG+=WarningsAsErrorsOn` will turn all warnings into errors which breaks the build. If you are working on a pull request you plan to submit to github for consideration, you should always run with this setting turned on, since it is required for all pull requests. NOTE: Putting this line into a file called "user_config.pri" in the top-level directory (same directory as `qgroundcontrol.pro`) will set this flag on all builds without interfering with the GIT history.
* Parallel builds: For non Windows builds, you can use the '-j#' option to run parellel builds.
* Location of built files: Individual build file results can be found in the `build_debug` or `build_release` directories. The built executable can be found in the `debug` or `release` directory.
* If you get this error when running qgroundcontrol: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version 'GLIBCXX_3.4.20' not found. You need to either update to the latest gcc, or install the latest libstdc++.6 using: sudo apt-get install libstdc++6.
## Additional functionality
QGroundControl has functionality that is dependent on the operating system and libraries installed by the user. The following sections describe these features, their dependencies, and how to disable/alter them during the build process. These features can be forcibly enabled/disabled by specifying additional values to qmake.
### Opal-RT's RT-LAB simulator
Integration with Opal-RT's RT-LAB simulator can be enabled on Windows by installing RT-LAB 7.2.4. This allows vehicles to be simulated in RT-LAB and communicate directly with QGC on the same computer as if the UAS was actually deployed. This support is enabled by default once the requisite RT-LAB software is installed. Disabling this can be done by adding `DEFINES+=DISABLE_RTLAB` to qmake.
### XBee support
QGroundControl can talk to XBee wireless devices using their proprietary protocol directly on Windows and Linux platforms. This support is not necessary if you're not using XBee devices or aren't using their proprietary protocol. On Windows, the necessary dependencies are included in this repository and no additional steps are required. For Linux, change to the `libs/thirdParty/libxbee` folder and run `make;sudo make install` to install libxbee on your system (uninstalling can be done with a `sudo make uninstall`). `qmake` will automatically detect the library on Linux, so no other work is necessary.
To disable XBee support you may add `DEFINES+=DISABLE_XBEE` to qmake.
### Video Streaming
Check the [Video Streaming](https://github.com/mavlink/qgroundcontrol/tree/master/src/VideoStreaming) directory for further instructions.
Key Links:
* [Website](http://qgroundcontrol.com) (qgroundcontrol.com)
* [User Manual](https://docs.qgroundcontrol.com/en/)
* [Developer Guide](https://dev.qgroundcontrol.com/en/)
* [Discussion/Support](https://docs.qgroundcontrol.com/en/Support/Support.html)
* [Contributing](https://dev.qgroundcontrol.com/en/contribute/)
* [License](https://github.com/mavlink/qgroundcontrol/blob/master/COPYING.md)
......@@ -45,6 +45,7 @@ Vagrant.configure(2) do |config|
$config_shell = <<-'SHELL'
set -e
set -x
export %{build_env}
export JOBS=$((`cat /proc/cpuinfo | grep -c ^processor`+1))
......
......@@ -59,7 +59,15 @@
<!-- Support devices without USB host mode since there are other connection types -->
<uses-feature android:name="android.hardware.usb.host" android:required="false"/>
<uses-feature android:name="android.hardware.location.GPS" android:required="false" />
<!-- Support devices without Bluetooth since there are other connection types -->
<uses-feature android:name="android.hardware.bluetooth" android:required="false"/>
<!-- Support devices that don't have location services -->
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false"/>
<uses-feature android:name="android.hardware.location" android:required="false"/>
<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
Remove the comment if you do not require these default features. -->
<!-- %%INSERT_FEATURES -->
......
buildscript {
repositories {
jcenter()
maven {
url "http://repo1.maven.org/maven2"
}
}
dependencies {
......@@ -51,6 +54,10 @@ android {
}
}
aaptOptions {
cruncherEnabled = false
}
lintOptions {
abortOnError false
}
......
#!/bin/bash -x
if [[ $# -eq 0 ]]; then
echo 'MakeQtTravisTarball.sh QtDirectory QtFullVersion QtBaseVersion BuildType'
exit 1
if [ $# -ne 2 ]; then
echo 'MakeQtTravisTarball.sh QtDirectory BuildType'
exit 1
fi
QT_DIRECTORY=$1
if [ ! -d ${QT_DIRECTORY} ]; then
echo 'Specify directory for Qt Directory.'
exit 1
echo 'Specify directory for Qt Directory to copy from.'
exit 1
fi
QT_FULL_VERSION=$2
if [ ! -d ${QT_DIRECTORY}/${QT_FULL_VERSION} ]; then
echo 'Qt version directory not found'
exit 1
fi
QT_BASE_VERSION=$3
QT_FULL_VERSION=5.11.0
QT_BASE_VERSION=5.11
QT_BUILD_TYPE=$4
QT_BUILD_TYPE=$2
if [ ! -d ${QT_DIRECTORY}/${QT_FULL_VERSION}/${QT_BUILD_TYPE} ]; then
echo 'Qt build type directory not found'
exit 1
echo 'Qt build type directory not found. Specify example: clang_64'
exit 1
fi
mkdir -p Qt${QT_BASE_VERSION}-${QT_BUILD_TYPE}/${QT_FULL_VERSION}/${QT_BUILD_TYPE}
......
No preview for this file type
......@@ -73,8 +73,12 @@ doinstall:
File /r /x ${EXENAME}.pdb /x ${EXENAME}.lib /x ${EXENAME}.exp ${DESTDIR}\*.*
File deploy\px4driver.msi
WriteUninstaller $INSTDIR\${EXENAME}-Uninstall.exe
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$\"$INSTDIR\${EXENAME}-Uninstall.exe$\""
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}"
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$\"$INSTDIR\${EXENAME}-Uninstall.exe$\""
SetRegView 64
WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\${EXENAME}.exe" "DumpCount" 5
WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\${EXENAME}.exe" "DumpType" 2
WriteRegExpandStr HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\${EXENAME}.exe" "DumpFolder" "%LOCALAPPDATA%\QGCCrashDumps"
; Only attempt to install the PX4 driver if the version isn't present
!define ROOTKEY "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\434608CF2B6E31F0DDBA5C511053F957B55F098E"
......@@ -106,7 +110,8 @@ Section "Uninstall"
RMDir /r /REBOOTOK "$SMPROGRAMS\$StartMenuFolder\"
SetShellVarContext current
RMDir /r /REBOOTOK "$APPDATA\${ORGNAME}\"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}"
DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}"
DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\${EXENAME}.exe"
SectionEnd
Section "create Start Menu Shortcuts"
......
Subproject commit 37d14af47d783eb516959cc10e4cf70d66e927c0
Subproject commit 033fa8e7a4a75a0c3f17cea57e3be8966e05f770
......@@ -174,6 +174,7 @@
<file alias="subVehicleArrowOpaque.png">src/FlightMap/Images/sub.png</file>
<file alias="AlertAircraft.svg">src/FlightMap/Images/AlertAircraft.svg</file>
<file alias="AwarenessAircraft.svg">src/FlightMap/Images/AwarenessAircraft.svg</file>
<file alias="check.svg">resources/check.svg</file>
</qresource>
<qresource prefix="/res">
<file alias="action.svg">resources/action.svg</file>
......
......@@ -240,6 +240,7 @@ AndroidBuild || iOSBuild {
QT += \
printsupport \
serialport \
charts \
}
contains(DEFINES, QGC_ENABLE_BLUETOOTH) {
......@@ -392,12 +393,14 @@ HEADERS += \
src/api/QGCOptions.h \
src/api/QGCSettings.h \
src/api/QmlComponentInfo.h \
src/comm/HeartbeatTimer.h
SOURCES += \
src/api/QGCCorePlugin.cc \
src/api/QGCOptions.cc \
src/api/QGCSettings.cc \
src/api/QmlComponentInfo.cc \
src/comm/HeartbeatTimer.cc
#
# Unit Test specific configuration goes here (requires full debug build with all plugins)
......@@ -432,7 +435,7 @@ DebugBuild { PX4FirmwarePlugin { PX4FirmwarePluginFactory { APMFirmwarePlugin {
src/MissionManager/SimpleMissionItemTest.h \
src/MissionManager/SpeedSectionTest.h \
src/MissionManager/StructureScanComplexItemTest.h \
src/MissionManager/SurveyMissionItemTest.h \
src/MissionManager/SurveyComplexItemTest.h \
src/MissionManager/TransectStyleComplexItemTest.h \
src/MissionManager/VisualMissionItemTest.h \
src/qgcunittest/FileDialogTest.h \
......@@ -473,7 +476,7 @@ DebugBuild { PX4FirmwarePlugin { PX4FirmwarePluginFactory { APMFirmwarePlugin {
src/MissionManager/SimpleMissionItemTest.cc \
src/MissionManager/SpeedSectionTest.cc \
src/MissionManager/StructureScanComplexItemTest.cc \
src/MissionManager/SurveyMissionItemTest.cc \
src/MissionManager/SurveyComplexItemTest.cc \
src/MissionManager/TransectStyleComplexItemTest.cc \
src/MissionManager/VisualMissionItemTest.cc \
src/qgcunittest/FileDialogTest.cc \
......@@ -512,6 +515,7 @@ HEADERS += \
src/Joystick/Joystick.h \
src/Joystick/JoystickManager.h \
src/JsonHelper.h \
src/KMLFileHelper.h \
src/LogCompressor.h \
src/MG.h \
src/MissionManager/CameraCalc.h \
......@@ -545,7 +549,7 @@ HEADERS += \
src/MissionManager/Section.h \
src/MissionManager/SpeedSection.h \
src/MissionManager/StructureScanComplexItem.h \
src/MissionManager/SurveyMissionItem.h \
src/MissionManager/SurveyComplexItem.h \
src/MissionManager/TransectStyleComplexItem.h \
src/MissionManager/VisualMissionItem.h \
src/PositionManager/PositionManager.h \
......@@ -588,6 +592,7 @@ HEADERS += \
src/Settings/UnitsSettings.h \
src/Settings/VideoSettings.h \
src/Terrain/TerrainQuery.h \
src/TerrainTile.h \
src/Vehicle/MAVLinkLogManager.h \
src/VehicleSetup/JoystickConfigController.h \
src/comm/LinkConfiguration.h \
......@@ -709,6 +714,7 @@ SOURCES += \
src/Joystick/Joystick.cc \
src/Joystick/JoystickManager.cc \
src/JsonHelper.cc \
src/KMLFileHelper.cc \
src/LogCompressor.cc \
src/MissionManager/CameraCalc.cc \
src/MissionManager/CameraSection.cc \
......@@ -740,7 +746,7 @@ SOURCES += \
src/MissionManager/SimpleMissionItem.cc \
src/MissionManager/SpeedSection.cc \
src/MissionManager/StructureScanComplexItem.cc \
src/MissionManager/SurveyMissionItem.cc \
src/MissionManager/SurveyComplexItem.cc \
src/MissionManager/TransectStyleComplexItem.cc \
src/MissionManager/VisualMissionItem.cc \
src/PositionManager/PositionManager.cpp \
......@@ -782,6 +788,7 @@ SOURCES += \
src/Settings/UnitsSettings.cc \
src/Settings/VideoSettings.cc \
src/Terrain/TerrainQuery.cc \
src/TerrainTile.cc\
src/Vehicle/MAVLinkLogManager.cc \
src/VehicleSetup/JoystickConfigController.cc \
src/comm/LinkConfiguration.cc \
......@@ -1057,7 +1064,7 @@ HEADERS += \
src/FactSystem/FactGroup.h \
src/FactSystem/FactMetaData.h \
src/FactSystem/FactSystem.h \
src/FactSystem/FactValidator.h \
src/FactSystem/FactValueSliderListModel.h \
src/FactSystem/ParameterManager.h \
src/FactSystem/SettingsFact.h \
......@@ -1067,7 +1074,7 @@ SOURCES += \
src/FactSystem/FactGroup.cc \
src/FactSystem/FactMetaData.cc \
src/FactSystem/FactSystem.cc \
src/FactSystem/FactValidator.cc \
src/FactSystem/FactValueSliderListModel.cc \
src/FactSystem/ParameterManager.cc \
src/FactSystem/SettingsFact.cc \
......
......@@ -9,10 +9,11 @@
<file alias="GPSRTKIndicator.qml">src/ui/toolbar/GPSRTKIndicator.qml</file>
<file alias="MessageIndicator.qml">src/ui/toolbar/MessageIndicator.qml</file>
<file alias="ModeIndicator.qml">src/ui/toolbar/ModeIndicator.qml</file>
<file alias="VTOLModeIndicator.qml">src/ui/toolbar/VTOLModeIndicator.qml</file>
<file alias="VTOLModeIndicator.qml">src/ui/toolbar/VTOLModeIndicator.qml</file>
<file alias="RCRSSIIndicator.qml">src/ui/toolbar/RCRSSIIndicator.qml</file>
<file alias="TelemetryRSSIIndicator.qml">src/ui/toolbar/TelemetryRSSIIndicator.qml</file>
<file alias="JoystickIndicator.qml">src/ui/toolbar/JoystickIndicator.qml</file>
<file alias="LinkIndicator.qml">src/ui/toolbar/LinkIndicator.qml</file>
</qresource>
<qresource prefix="/qml">
<file alias="CorridorScanEditor.qml">src/PlanView/CorridorScanEditor.qml</file>
......@@ -85,7 +86,11 @@
<file alias="QGroundControl/Controls/PageView.qml">src/QmlControls/PageView.qml</file>
<file alias="QGroundControl/Controls/ParameterEditor.qml">src/QmlControls/ParameterEditor.qml</file>
<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/PlanToolBar.qml">src/PlanView/PlanToolBar.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/PreFlightCheckList.qml">src/QmlControls/PreFlightCheckList.qml</file>
<file alias="QGroundControl/Controls/QGCButton.qml">src/QmlControls/QGCButton.qml</file>
<file alias="QGroundControl/Controls/QGCCheckBox.qml">src/QmlControls/QGCCheckBox.qml</file>
<file alias="QGroundControl/Controls/QGCColoredImage.qml">src/QmlControls/QGCColoredImage.qml</file>
......@@ -118,14 +123,14 @@
<file alias="QGroundControl/Controls/RallyPointMapVisuals.qml">src/PlanView/RallyPointMapVisuals.qml</file>
<file alias="QGroundControl/Controls/RCChannelMonitor.qml">src/QmlControls/RCChannelMonitor.qml</file>
<file alias="QGroundControl/Controls/RoundButton.qml">src/QmlControls/RoundButton.qml</file>
<file alias="QGroundControl/Controls/SectionHeader.qml">src/PlanView/SectionHeader.qml</file>
<file alias="QGroundControl/Controls/SectionHeader.qml">src/QmlControls/SectionHeader.qml</file>
<file alias="QGroundControl/Controls/SetupPage.qml">src/AutoPilotPlugins/Common/SetupPage.qml</file>
<file alias="QGroundControl/Controls/SignalStrength.qml">src/ui/toolbar/SignalStrength.qml</file>
<file alias="QGroundControl/Controls/SimpleItemMapVisual.qml">src/PlanView/SimpleItemMapVisual.qml</file>
<file alias="QGroundControl/Controls/SliderSwitch.qml">src/QmlControls/SliderSwitch.qml</file>
<file alias="QGroundControl/Controls/SubMenuButton.qml">src/QmlControls/SubMenuButton.qml</file>
<file alias="QGroundControl/Controls/SurveyMapVisual.qml">src/PlanView/SurveyMapVisual.qml</file>
<file alias="QGroundControl/Controls/TransectStyleComplexItemStats.qml">src/PlanView/TransectStyleComplexItemStats.qml</file>
<file alias="QGroundControl/Controls/TransectStyleComplexItemStats.qml">src/PlanView/TransectStyleComplexItemStats.qml</file>
<file alias="QGroundControl/Controls/ToolStrip.qml">src/QmlControls/ToolStrip.qml</file>
<file alias="QGroundControl/Controls/VehicleRotationCal.qml">src/QmlControls/VehicleRotationCal.qml</file>
<file alias="QGroundControl/Controls/VehicleSummaryRow.qml">src/QmlControls/VehicleSummaryRow.qml</file>
......@@ -138,6 +143,7 @@
<file alias="QGroundControl/FactControls/FactTextField.qml">src/FactSystem/FactControls/FactTextField.qml</file>
<file alias="QGroundControl/FactControls/FactTextFieldGrid.qml">src/FactSystem/FactControls/FactTextFieldGrid.qml</file>
<file alias="QGroundControl/FactControls/FactTextFieldRow.qml">src/FactSystem/FactControls/FactTextFieldRow.qml</file>
<file alias="QGroundControl/FactControls/FactValueSlider.qml">src/FactSystem/FactControls/FactValueSlider.qml</file>
<file alias="QGroundControl/FactControls/qmldir">src/FactSystem/FactControls/qmldir</file>
<file alias="QGroundControl/FlightDisplay/FlightDisplayView.qml">src/FlightDisplay/FlightDisplayView.qml</file>
<file alias="QGroundControl/FlightDisplay/FlightDisplayViewMap.qml">src/FlightDisplay/FlightDisplayViewMap.qml</file>
......@@ -148,6 +154,12 @@
<file alias="QGroundControl/FlightDisplay/GuidedActionsController.qml">src/FlightDisplay/GuidedActionsController.qml</file>
<file alias="QGroundControl/FlightDisplay/GuidedAltitudeSlider.qml">src/FlightDisplay/GuidedAltitudeSlider.qml</file>
<file alias="QGroundControl/FlightDisplay/MultiVehicleList.qml">src/FlightDisplay/MultiVehicleList.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightAHRSCheck.qml">src/FlightDisplay/PreFlightAHRSCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightBatteryCheck.qml">src/FlightDisplay/PreFlightBatteryCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightCheckModel.qml">src/FlightDisplay/PreFlightCheckModel.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightRCCheck.qml">src/FlightDisplay/PreFlightRCCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightSensorsCheck.qml">src/FlightDisplay/PreFlightSensorsCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightSoundCheck.qml">src/FlightDisplay/PreFlightSoundCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/qmldir">src/FlightDisplay/qmldir</file>
<file alias="QGroundControl/FlightMap/CameraTriggerIndicator.qml">src/FlightMap/MapItems/CameraTriggerIndicator.qml</file>
<file alias="QGroundControl/FlightMap/CenterMapDropButton.qml">src/FlightMap/Widgets/CenterMapDropButton.qml</file>
......@@ -222,8 +234,10 @@
<file alias="USBBoardInfo.json">src/comm/USBBoardInfo.json</file>
<file alias="Vehicle/BatteryFact.json">src/Vehicle/BatteryFact.json</file>
<file alias="Vehicle/ClockFact.json">src/Vehicle/ClockFact.json</file>
<file alias="Vehicle/DistanceSensorFact.json">src/Vehicle/DistanceSensorFact.json</file>
<file alias="Vehicle/GPSFact.json">src/Vehicle/GPSFact.json</file>
<file alias="Vehicle/GPSRTKFact.json">src/Vehicle/GPSRTKFact.json</file>
<file alias="Vehicle/SetpointFact.json">src/Vehicle/SetpointFact.json</file>
<file alias="Vehicle/SubmarineFact.json">src/Vehicle/SubmarineFact.json</file>
<file alias="Vehicle/TemperatureFact.json">src/Vehicle/TemperatureFact.json</file>
<file alias="Vehicle/VehicleFact.json">src/Vehicle/VehicleFact.json</file>
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
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:xlink="http://www.w3.org/1999/xlink"
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="check.svg"><metadata
id="metadata3416"><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 /></cc:Work></rdf:RDF></metadata><defs
id="defs3414"><linearGradient
id="linearGradient4141"
osb:paint="solid"><stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4143" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4141"
id="linearGradient4145"
x1="48.508473"
y1="58.423729"
x2="79.322032"
y2="58.423729"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.8414091,0,0,2.2407508,-82.18242,-94.289127)" /></defs><sodipodi:namedview
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1855"
inkscape:window-height="1056"
id="namedview3412"
showgrid="false"
inkscape:zoom="3.2777778"
inkscape:cx="-54.305085"
inkscape:cy="36"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" /><style
type="text/css"
id="style3406">
.st0{fill:#66BD59;stroke:#FFFFFF;stroke-width:5;stroke-miterlimit:10;}
.st1{fill:none;stroke:#FFFFFF;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style><polyline
class="st1"
points="55.1,19.8 30.2,52.2 16.9,36.5 "
id="polyline3410"
transform="matrix(0.85559226,0,0,0.85559226,5.1269823,8.2041673)"
style="fill:none;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10" /><style
id="style3419"
type="text/css">
.st0{fill:none;stroke:#FFFFFF;stroke-width:3;stroke-miterlimit:10;}
.st1{fill:none;stroke:#FFFFFF;stroke-width:8;stroke-miterlimit:10;}
.st2{fill:#FFFFFF;}
</style><circle
style="fill:none;stroke:url(#linearGradient4145);stroke-width:3.25963402;stroke-miterlimit:4;stroke-dasharray:none"
id="path3339"
cx="35.5117"
cy="36.62389"
r="28.370182" /></svg>
\ No newline at end of file
......@@ -288,7 +288,7 @@ Item {
height: width
radius: 2
color: _colorGray
anchors.verticalCenter: parent.verticalCenter
Layout.alignment: Qt.AlignVCenter
QGCColoredImage {
id: pencilIcon
width: height
......
......@@ -70,8 +70,7 @@ void GeoTagController::startTagging(void)
QDir imageDirectory = QDir(_worker.imageDirectory());
if(!imageDirectory.exists()) {
_errorMessage = tr("Cannot find the image directory");
emit errorMessageChanged(_errorMessage);
_setErrorMessage(tr("Cannot find the image directory"));
return;
}
if(_worker.saveDirectory() == "") {
......@@ -83,23 +82,20 @@ void GeoTagController::startTagging(void)
msgBox.setWindowModality(Qt::ApplicationModal);
msgBox.addButton(tr("Replace"), QMessageBox::ActionRole);
if (msgBox.exec() == QMessageBox::Cancel) {
_errorMessage = tr("Images have already been tagged");
emit errorMessageChanged(_errorMessage);
_setErrorMessage(tr("Images have already been tagged"));
return;
}
QDir oldTaggedFolder = QDir(_worker.imageDirectory() + "/TAGGED");
oldTaggedFolder.removeRecursively();
if(!imageDirectory.mkdir(_worker.imageDirectory() + "/TAGGED")) {
_errorMessage = tr("Couldn't replace the previously tagged images");
emit errorMessageChanged(_errorMessage);
_setErrorMessage(tr("Couldn't replace the previously tagged images"));
return;
}
}
} else {
QDir saveDirectory = QDir(_worker.saveDirectory());
if(!saveDirectory.exists()) {
_errorMessage = tr("Cannot find the save directory");
emit errorMessageChanged(_errorMessage);
_setErrorMessage(tr("Cannot find the save directory"));
return;
}
saveDirectory.setFilter(QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::Writable);
......@@ -115,15 +111,13 @@ void GeoTagController::startTagging(void)
msgBox.setWindowModality(Qt::ApplicationModal);
msgBox.addButton(tr("Replace"), QMessageBox::ActionRole);
if (msgBox.exec() == QMessageBox::Cancel) {
_errorMessage = tr("Save folder not empty");
emit errorMessageChanged(_errorMessage);
_setErrorMessage(tr("Save folder not empty"));
return;
}
foreach(QString dirFile, imageList)
{
if(!saveDirectory.remove(dirFile)) {
_errorMessage = tr("Couldn't replace the existing images");
emit errorMessageChanged(_errorMessage);
_setErrorMessage(tr("Couldn't replace the existing images"));
return;
}
}
......@@ -144,6 +138,13 @@ void GeoTagController::_workerError(QString errorMessage)
emit errorMessageChanged(errorMessage);
}
void GeoTagController::_setErrorMessage(const QString& error)
{
_errorMessage = error;
emit errorMessageChanged(error);
}
GeoTagWorker::GeoTagWorker(void)
: _cancel(false)
, _logFile("")
......@@ -210,9 +211,10 @@ void GeoTagWorker::run(void)
// Instantiate appropriate parser
_triggerList.clear();
bool parseComplete = false;
if(isULog) {
QString errorString;
if (isULog) {
ULogParser parser;
parseComplete = parser.getTagsFromLog(log, _triggerList);
parseComplete = parser.getTagsFromLog(log, _triggerList, errorString);
} else {
PX4LogParser parser;
......@@ -227,7 +229,8 @@ void GeoTagWorker::run(void)
return;
} else {
qCDebug(GeotaggingLog) << "Log parsing failed";
emit error(tr("Log parsing failed - tagging cancelled"));
errorString = tr("%1 - tagging cancelled").arg(errorString.isEmpty() ? tr("Log parsing failed") : errorString);
emit error(errorString);
return;
}
}
......@@ -259,6 +262,11 @@ void GeoTagWorker::run(void)
int maxIndex = std::min(_imageIndices.count(), _triggerIndices.count());
maxIndex = std::min(maxIndex, _imageList.count());
for(int i = 0; i < maxIndex; i++) {
int imageIndex = _imageIndices[i];
if (imageIndex >= _imageList.count()) {
emit error(tr("Geotagging failed. Image requested not present."));
return;
}
QFile fileRead(_imageList.at(_imageIndices[i]).absoluteFilePath());
if (!fileRead.open(QIODevice::ReadOnly)) {
emit error(tr("Geotagging failed. Couldn't open an image."));
......
......@@ -117,8 +117,9 @@ signals:
void errorMessageChanged (QString errorMessage);
private slots:
void _workerProgressChanged(double progress);
void _workerError(QString errorMsg);
void _workerProgressChanged (double progress);
void _workerError (QString errorMsg);
void _setErrorMessage (const QString& error);
private:
QString _errorMessage;
......
......@@ -124,8 +124,9 @@ AnalyzePage {
}
QGCButton {
text: geoController.inProgress ? qsTr("Cancel Tagging") : qsTr("Start Tagging")
width: ScreenTools.defaultFontPixelWidth * 30
text: geoController.inProgress ? qsTr("Cancel Tagging") : qsTr("Start Tagging")
width: ScreenTools.defaultFontPixelWidth * 30
onClicked: {
if (geoController.inProgress) {
geoController.cancelTagging()
......
......@@ -321,7 +321,7 @@ LogDownloadController::_logData(UASInterface* uas, uint32_t ofs, uint16_t id, ui
if(ofs <= _downloadData->entry->size()) {
const uint32_t chunk = ofs / kChunkSize;
if (chunk != _downloadData->current_chunk) {
qWarning() << "Ignored packet for out of order chunk" << chunk;
qWarning() << "Ignored packet for out of order chunk actual:expected" << chunk << _downloadData->current_chunk;
return;
}
const uint16_t bin = (ofs - chunk*kChunkSize) / MAVLINK_MSG_LOG_DATA_FIELD_DATA_LEN;
......
......@@ -51,8 +51,7 @@ AnalyzePage {
TableView {
id: tableView
anchors.top: parent.top
anchors.bottom: parent.bottom
Layout.fillHeight: true
model: logController.model
selectionMode: SelectionMode.MultiSelection
Layout.fillWidth: true
......@@ -155,7 +154,7 @@ AnalyzePage {
fileDialog.qgcView = logDownloadPage
fileDialog.title = qsTr("Select save directory")
fileDialog.selectExisting = true
fileDialog.folder = QGroundControl.settingsManager.appSettings.telemetrySavePath
fileDialog.folder = QGroundControl.settingsManager.appSettings.logSavePath
fileDialog.selectFolder = true
fileDialog.openForLoad()
}
......@@ -186,7 +185,7 @@ AnalyzePage {
message: qsTr("All log files will be erased permanently. Is this really what you want?")
function accept() {
logDownloadPage.hideDialog()
hideDialog()
logController.eraseAll()
}
}
......
......@@ -33,12 +33,25 @@ MavlinkConsoleController::~MavlinkConsoleController()
void
MavlinkConsoleController::sendCommand(QString command)
{
_history.append(command);
command.append("\n");
_sendSerialData(qPrintable(command));
_cursor_home_pos = -1;
_cursor = rowCount();
}
QString
MavlinkConsoleController::historyUp(const QString& current)
{
return _history.up(current);
}
QString
MavlinkConsoleController::historyDown(const QString& current)
{
return _history.down(current);
}
void
MavlinkConsoleController::_setActiveVehicle(Vehicle* vehicle)
{
......@@ -192,3 +205,43 @@ MavlinkConsoleController::writeLine(int line, const QByteArray &text)
auto idx = index(line);
setData(idx, data(idx, Qt::DisplayRole).toString() + text);
}
void MavlinkConsoleController::CommandHistory::append(const QString& command)
{
if (command.length() > 0) {
// do not append duplicates
if (_history.length() == 0 || _history.last() != command) {
if (_history.length() >= maxHistoryLength) {
_history.removeFirst();
}
_history.append(command);
}
}
_index = _history.length();
}
QString MavlinkConsoleController::CommandHistory::up(const QString& current)
{
if (_index <= 0)
return current;
--_index;
if (_index < _history.length()) {
return _history[_index];
}
return "";
}
QString MavlinkConsoleController::CommandHistory::down(const QString& current)
{
if (_index >= _history.length())
return current;
++_index;
if (_index < _history.length()) {
return _history[_index];
}
return "";
}
......@@ -27,13 +27,12 @@ class MavlinkConsoleController : public QStringListModel
public:
MavlinkConsoleController();
~MavlinkConsoleController();
virtual ~MavlinkConsoleController();
public slots:
void sendCommand(QString command);
Q_INVOKABLE void sendCommand(QString command);
signals:
void cursorChanged(int);
Q_INVOKABLE QString historyUp(const QString& current);
Q_INVOKABLE QString historyDown(const QString& current);
private slots:
void _setActiveVehicle (Vehicle* vehicle);
......@@ -44,10 +43,23 @@ private:
void _sendSerialData(QByteArray, bool close = false);
void writeLine(int line, const QByteArray &text);
class CommandHistory
{
public:
void append(const QString& command);
QString up(const QString& current);
QString down(const QString& current);
private:
static constexpr int maxHistoryLength = 100;
QList<QString> _history;
int _index = 0;
};
int _cursor_home_pos;
int _cursor;
QByteArray _incoming_buffer;
Vehicle* _vehicle;
QList<QMetaObject::Connection> _uas_connections;
CommandHistory _history;
};
......@@ -26,7 +26,7 @@ AnalyzePage {
pageName: qsTr("Mavlink Console")
pageDescription: qsTr("Mavlink Console provides a connection to the vehicle's system shell.")
property bool loaded: false
property bool isLoaded: false
Component {
id: pageComponent
......@@ -41,7 +41,7 @@ AnalyzePage {
onDataChanged: {
// Keep the view in sync if the button is checked
if (loaded) {
if (isLoaded) {
if (followTail.checked) {
listview.positionViewAtEnd();
}
......@@ -53,7 +53,7 @@ AnalyzePage {
id: delegateItem
Rectangle {
color: qgcPal.windowShade
height: Math.round(ScreenTools.defaultFontPixelHeight * 0.5 + field.height)
height: Math.round(ScreenTools.defaultFontPixelHeight * 0.1 + field.height)
width: listview.width
QGCLabel {
......@@ -69,11 +69,10 @@ AnalyzePage {
QGCListView {
Component.onCompleted: {
loaded = true
isLoaded = true
}
Layout.fillHeight: true
anchors.left: parent.left
anchors.right: parent.right
Layout.fillWidth: true
clip: true
id: listview
model: conController
......@@ -86,8 +85,7 @@ AnalyzePage {
}
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
Layout.fillWidth: true
QGCTextField {
id: command
Layout.fillWidth: true
......@@ -96,6 +94,15 @@ AnalyzePage {
conController.sendCommand(text)
text = ""
}
Keys.onPressed: {
if (event.key == Qt.Key_Up) {
text = conController.historyUp(text);
event.accepted = true;
} else if (event.key == Qt.Key_Down) {
text = conController.historyDown(text);
event.accepted = true;
}
}
}
QGCButton {
......@@ -105,7 +112,7 @@ AnalyzePage {
checked: true
onCheckedChanged: {
if (checked && loaded) {
if (checked && isLoaded) {
listview.positionViewAtEnd();
}
}
......
......@@ -86,11 +86,13 @@ bool ULogParser::parseFieldFormat(QString& fields)
return false;
}
bool ULogParser::getTagsFromLog(QByteArray& log, QList<GeoTagWorker::cameraFeedbackPacket>& cameraFeedback)
bool ULogParser::getTagsFromLog(QByteArray& log, QList<GeoTagWorker::cameraFeedbackPacket>& cameraFeedback, QString& errorMessage)
{
errorMessage.clear();
//verify it's an ULog file
if(!log.contains(_ULogMagic)) {
qWarning() << "Could not detect ULog file header magic";
errorMessage = tr("Could not detect ULog file header magic");
return false;
}
......@@ -139,15 +141,10 @@ bool ULogParser::getTagsFromLog(QByteArray& log, QList<GeoTagWorker::cameraFeedb
case (int)ULogMessageType::DATA:
{
if (!geotagFound) {
qWarning() << "Could not detect geotag packets in ULog";
return false;
}
uint16_t msgID = -1;
memcpy(&msgID, log.data() + index + ULOG_MSG_HEADER_LEN, 2);
if(msgID == _cameraCaptureMsgID) {
if (geotagFound && msgID == _cameraCaptureMsgID) {
// Completely dynamic parsing, so that changing/reordering the message format will not break the parser
GeoTagWorker::cameraFeedbackPacket feedback;
......@@ -179,5 +176,10 @@ bool ULogParser::getTagsFromLog(QByteArray& log, QList<GeoTagWorker::cameraFeedb
}
if (cameraFeedback.count() == 0) {
errorMessage = tr("Could not detect camera_capture packets in ULog");
return false;
}
return true;
}
......@@ -3,6 +3,7 @@
#include <QGeoCoordinate>
#include <QDebug>
#include <QCoreApplication>
#include "GeoTagController.h"
......@@ -10,10 +11,14 @@
class ULogParser
{
Q_DECLARE_TR_FUNCTIONS(ULogParser)
public:
ULogParser();
~ULogParser();
bool getTagsFromLog(QByteArray& log, QList<GeoTagWorker::cameraFeedbackPacket>& cameraFeedback);
/// @return true: failed, errorMessage set
bool getTagsFromLog(QByteArray& log, QList<GeoTagWorker::cameraFeedbackPacket>& cameraFeedback, QString& errorMessage);
private:
......
......@@ -73,6 +73,7 @@ QString AudioOutput::fixTextMessageForAudio(const QString& string) {
QString match;
QString newNumber;
QString result = string;
//-- Look for codified terms
if(result.contains("ERR ", Qt::CaseInsensitive)) {
result.replace("ERR ", "error ", Qt::CaseInsensitive);
......@@ -118,6 +119,9 @@ QString AudioOutput::fixTextMessageForAudio(const QString& string) {
if(result.contains(" ADSB ", Qt::CaseInsensitive)) {
result.replace(" ADSB ", " Hey Dee Ess Bee ", Qt::CaseInsensitive);
}
if(result.contains(" EKF ", Qt::CaseInsensitive)) {
result.replace(" EKF ", " Eee Kay Eff ", Qt::CaseInsensitive);
}
// Convert negative numbers
QRegularExpression re(QStringLiteral("(-)[0-9]*\\.?[0-9]"));
......@@ -125,9 +129,18 @@ QString AudioOutput::fixTextMessageForAudio(const QString& string) {
while (reMatch.hasMatch()) {
if (!reMatch.captured(1).isNull()) {
// There is a negative prefix
qDebug() << "negative" << reMatch.captured(1) << reMatch.capturedStart(1) << reMatch.capturedEnd(1);
result.replace(reMatch.capturedStart(1), reMatch.capturedEnd(1) - reMatch.capturedStart(1), tr(" negative "));
qDebug() << result;
}
reMatch = re.match(result);
}
// Convert real number with decimal point
re.setPattern(QStringLiteral("([0-9]+)(\\.)([0-9]+)"));
reMatch = re.match(result);
while (reMatch.hasMatch()) {
if (!reMatch.captured(2).isNull()) {
// There is a decimal point
result.replace(reMatch.capturedStart(2), reMatch.capturedEnd(2) - reMatch.capturedStart(2), tr(" point "));
}
reMatch = re.match(result);
}
......@@ -138,9 +151,7 @@ QString AudioOutput::fixTextMessageForAudio(const QString& string) {
while (reMatch.hasMatch()) {
if (!reMatch.captured(1).isNull()) {
// There is a meter postfix
qDebug() << "meters" << reMatch.captured(1) << reMatch.capturedStart(1) << reMatch.capturedEnd(1);
result.replace(reMatch.capturedStart(1), reMatch.capturedEnd(1) - reMatch.capturedStart(1), tr(" meters"));
qDebug() << result;
}
reMatch = re.match(result);
}
......
......@@ -18,7 +18,7 @@ AudioOutputTest::AudioOutputTest(void)
void AudioOutputTest::_testSpokenReplacements(void)
{
QString result = AudioOutput::fixTextMessageForAudio(QStringLiteral("-10.5m, -10.5m. -10.5 m"));
QCOMPARE(result, QStringLiteral(" negative 10.5 meters, negative 10.5 meters. negative 10.5 meters"));
QCOMPARE(result, QStringLiteral(" negative 10 point 5 meters, negative 10 point 5 meters. negative 10 point 5 meters"));
result = AudioOutput::fixTextMessageForAudio(QStringLiteral("-10m -10 m"));
QCOMPARE(result, QStringLiteral(" negative 10 meters negative 10 meters"));
result = AudioOutput::fixTextMessageForAudio(QStringLiteral("foo -10m -10 m bar"));
......
......@@ -83,10 +83,9 @@ SetupPage {
id: newFramePageComponent
Grid {
anchors.left: parent.left
anchors.right: parent.right
spacing: _margins
columns: 2
width: availableWidth
spacing: _margins
columns: 2
QGCLabel {
text: qsTr("Frame Class:")
......
......@@ -18,36 +18,36 @@ FactPanel {
factPanel: panel
}
property bool _useOldFrameParam: controller.parameterExists(-1, "FRAME")
property Fact _oldFrameParam: controller.getParameterFact(-1, "FRAME", false)
property Fact _newFrameParam: controller.getParameterFact(-1, "FRAME_CLASS", false)
property Fact _frameTypeParam: controller.getParameterFact(-1, "FRAME_TYPE", false)
property bool _frameAvailable: controller.parameterExists(-1, "FRAME")
property Fact _frame: controller.getParameterFact(-1, "FRAME", false)
property Fact _frameClass: controller.getParameterFact(-1, "FRAME_CLASS", false)
property Fact _frameType: controller.getParameterFact(-1, "FRAME_TYPE", false)
Column {
anchors.fill: parent
VehicleSummaryRow {
labelText: qsTr("Frame Type:")
valueText: controller.currentAirframeTypeName() + " " + _oldFrameParam.enumStringValue
visible: _useOldFrameParam
labelText: qsTr("Frame Type")
valueText: visible ? controller.currentAirframeTypeName() + " " + _frame.enumStringValue : ""
visible: _frameAvailable
}
VehicleSummaryRow {
labelText: qsTr("Frame Class:")
valueText: _newFrameParam.enumStringValue
visible: !_useOldFrameParam
labelText: qsTr("Frame Class")
valueText: visible ? _frameClass.enumStringValue : ""
visible: !_frameAvailable
}
VehicleSummaryRow {
labelText: qsTr("Frame Type:")
valueText: _frameTypeParam.enumStringValue
visible: !_useOldFrameParam
labelText: qsTr("Frame Type")
valueText: visible ? _frameType.enumStringValue : ""
visible: !_frameAvailable
}
VehicleSummaryRow {
labelText: qsTr("Firmware Version:")
labelText: qsTr("Firmware Version")
valueText: activeVehicle.firmwareMajorVersion == -1 ? qsTr("Unknown") : activeVehicle.firmwareMajorVersion + "." + activeVehicle.firmwareMinorVersion + "." + activeVehicle.firmwarePatchVersion + activeVehicle.firmwareVersionTypeString
}
}
......
......@@ -170,17 +170,29 @@ SetupPage {
ListModel {
id: gimbalOutModel
// It appears that QGCComboBox can't handle models that don't have a initial item
// after onModelChanged
ListElement { text: qsTr("Disabled"); value: 0 }
ListElement { text: qsTr("Channel 5"); value: 5 }
ListElement { text: qsTr("Channel 6"); value: 6 }
ListElement { text: qsTr("Channel 7"); value: 7 }
ListElement { text: qsTr("Channel 8"); value: 8 }
ListElement { text: qsTr("Channel 9"); value: 9 }
ListElement { text: qsTr("Channel 10"); value: 10 }
ListElement { text: qsTr("Channel 11"); value: 11 }
ListElement { text: qsTr("Channel 12"); value: 12 }
ListElement { text: qsTr("Channel 13"); value: 13 }
ListElement { text: qsTr("Channel 14"); value: 14 }
function update(number) {
// Not enough channels
if(number < 6) {
return
}
for(var i = 5; i <= number; i++) {
var text = qsTr("Channel ") + i
append({"text": text, "value": i})
}
}
Component.onCompleted: {
// Number of main outputs
var baseValue = 8
// Extra outputs
// http://ardupilot.org/copter/docs/parameters.html#brd-pwm-count-auxiliary-pin-config
var brd_pwm_count_value = controller.getParameterFact(-1, "BRD_PWM_COUNT").value
update(8 + (brd_pwm_count_value == 7 ? 3 : brd_pwm_count_value))
}
}
Component {
......
......@@ -27,22 +27,22 @@ FactPanel {
VehicleSummaryRow {
visible: _mountTypeExists
labelText: qsTr("Gimbal type:")
labelText: qsTr("Gimbal type")
valueText: _mountTypeValue
}
VehicleSummaryRow {
labelText: qsTr("Tilt input channel:")
labelText: qsTr("Tilt input channel")
valueText: _mountRCInTilt.enumStringValue
}
VehicleSummaryRow {
labelText: qsTr("Pan input channel:")
labelText: qsTr("Pan input channel")
valueText: _mountRCInPan.enumStringValue
}
VehicleSummaryRow {
labelText: qsTr("Roll input channel:")
labelText: qsTr("Roll input channel")
valueText: _mountRCInRoll.enumStringValue
}
}
......
......@@ -68,7 +68,7 @@ void APMFlightModesComponentController::_rcChannelsChanged(int channelCount, int
for (int i=0; i<6; i++) {
_rgChannelOptionEnabled[i] = QVariant(false);
channelValue = pwmValues[i+6];
if (channelValue != -1 && channelValue > 1800) {
if (channelValue > 1800) {
_rgChannelOptionEnabled[i] = QVariant(true);
}
}
......
......@@ -27,32 +27,32 @@ FactPanel {
anchors.fill: parent
VehicleSummaryRow {
labelText: qsTr("Flight Mode 1:")
labelText: qsTr("Flight Mode 1")
valueText: flightMode1.enumStringValue
}
VehicleSummaryRow {
labelText: qsTr("Flight Mode 2:")
labelText: qsTr("Flight Mode 2")
valueText: flightMode2.enumStringValue
}
VehicleSummaryRow {
labelText: qsTr("Flight Mode 3:")
labelText: qsTr("Flight Mode 3")
valueText: flightMode3.enumStringValue
}
VehicleSummaryRow {
labelText: qsTr("Flight Mode 4:")
labelText: qsTr("Flight Mode 4")
valueText: flightMode4.enumStringValue
}
VehicleSummaryRow {
labelText: qsTr("Flight Mode 5:")
labelText: qsTr("Flight Mode 5")
valueText: flightMode5.enumStringValue
}
VehicleSummaryRow {
labelText: qsTr("Flight Mode 6:")
labelText: qsTr("Flight Mode 6")
valueText: flightMode6.enumStringValue
}
}
......
......@@ -132,17 +132,29 @@ SetupPage {
ListModel {
id: lightsOutModel
// It appears that QGCComboBox can't handle models that don't have a initial item
// after onModelChanged
ListElement { text: qsTr("Disabled"); value: 0 }
ListElement { text: qsTr("Channel 5"); value: 5 }
ListElement { text: qsTr("Channel 6"); value: 6 }
ListElement { text: qsTr("Channel 7"); value: 7 }
ListElement { text: qsTr("Channel 8"); value: 8 }
ListElement { text: qsTr("Channel 9"); value: 9 }
ListElement { text: qsTr("Channel 10"); value: 10 }
ListElement { text: qsTr("Channel 11"); value: 11 }
ListElement { text: qsTr("Channel 12"); value: 12 }
ListElement { text: qsTr("Channel 13"); value: 13 }
ListElement { text: qsTr("Channel 14"); value: 14 }
function update(number) {
// Not enough channels
if(number < 6) {
return
}
for(var i = 5; i <= number; i++) {
var text = qsTr("Channel ") + i
append({"text": text, "value": i})
}
}
Component.onCompleted: {
// Number of main outputs
var baseValue = 8
// Extra outputs
// http://ardupilot.org/copter/docs/parameters.html#brd-pwm-count-auxiliary-pin-config
var brd_pwm_count_value = controller.getParameterFact(-1, "BRD_PWM_COUNT").value
update(8 + (brd_pwm_count_value == 7 ? 3 : brd_pwm_count_value))
}
}
Component {
......
......@@ -89,12 +89,12 @@ FactPanel {
anchors.fill: parent
VehicleSummaryRow {
labelText: qsTr("Lights Output 1:")
labelText: qsTr("Lights Output 1")
valueText: lightsOutModel.get(lightsLoader.lights1OutIndex).text
}
VehicleSummaryRow {
labelText: qsTr("Lights Output 2:")
labelText: qsTr("Lights Output 2")
valueText: lightsOutModel.get(lightsLoader.lights2OutIndex).text
}
}
......
......@@ -20,18 +20,19 @@ class APMPowerComponent : public VehicleComponent
public:
APMPowerComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent = NULL);
// Virtuals from VehicleComponent
QStringList setupCompleteChangedTriggerList(void) const final;
// Overrides from VehicleComponent
QStringList setupCompleteChangedTriggerList(void) const override;
// Virtuals from VehicleComponent
QString name (void) const final;
QString description (void) const final;
QString iconResource (void) const final;
bool requiresSetup (void) const final;
bool setupComplete (void) const final;
QUrl setupSource (void) const final;
QUrl summaryQmlSource (void) const final;
QString name (void) const override;
QString description (void) const override;
QString iconResource (void) const override;
bool requiresSetup (void) const override;
bool setupComplete (void) const override;
QUrl setupSource (void) const override;
QUrl summaryQmlSource (void) const override;
bool allowSetupWhileArmed (void) const override { return true; }
private:
const QString _name;
QVariantList _summaryItems;
......
......@@ -24,20 +24,37 @@ FactPanel {
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
FactPanelController { id: controller; factPanel: panel }
property Fact battCapacity: controller.getParameterFact(-1, "BATT_CAPACITY")
property Fact battMonitor: controller.getParameterFact(-1, "BATT_MONITOR")
property bool _batt2MonitorAvailable: controller.parameterExists(-1, "BATT2_MONITOR")
property bool _batt2CapacityAvailable: controller.parameterExists(-1, "BATT2_CAPACITY")
property Fact _battCapacity: controller.getParameterFact(-1, "BATT_CAPACITY")
property Fact _batt2Capacity: controller.getParameterFact(-1, "BATT2_CAPACITY", false /* reportMissing */)
property Fact _battMonitor: controller.getParameterFact(-1, "BATT_MONITOR")
property Fact _batt2Monitor: controller.getParameterFact(-1, "BATT2_MONITOR", false /* reportMissing */)
Column {
anchors.fill: parent
VehicleSummaryRow {
labelText: qsTr("Battery monitor:")
valueText: battMonitor.enumStringValue
labelText: qsTr("Battery monitor")
valueText: _battMonitor.enumStringValue
}
VehicleSummaryRow {
labelText: qsTr("Battery capacity")
valueText: _battCapacity.valueString + " " + _battCapacity.units
}
VehicleSummaryRow {
labelText: qsTr("Battery2 monitor")
valueText: _batt2MonitorAvailable ? _batt2Monitor.enumStringValue : ""
visible: _batt2MonitorAvailable
}
VehicleSummaryRow {
labelText: qsTr("Battery capacity:")
valueText: battCapacity.valueString + " " + battCapacity.units
labelText: qsTr("Battery2 capacity")
valueText: _batt2CapacityAvailable ? _batt2Capacity.valueString + " " + _battCapacity.units : ""
visible: _batt2CapacityAvailable
}
}
}
......@@ -23,22 +23,22 @@ FactPanel {
anchors.fill: parent
VehicleSummaryRow {
labelText: qsTr("Roll:")
labelText: qsTr("Roll")
valueText: mapRollFact.value == 0 ? qsTr("Setup required") : qsTr("Channel %1").arg(mapRollFact.valueString)
}
VehicleSummaryRow {
labelText: qsTr("Pitch:")
labelText: qsTr("Pitch")
valueText: mapPitchFact.value == 0 ? qsTr("Setup required") : qsTr("Channel %1").arg(mapPitchFact.valueString)
}
VehicleSummaryRow {
labelText: qsTr("Yaw:")
labelText: qsTr("Yaw")
valueText: mapYawFact.value == 0 ? qsTr("Setup required") : qsTr("Channel %1").arg(mapYawFact.valueString)
}
VehicleSummaryRow {
labelText: qsTr("Throttle:")
labelText: qsTr("Throttle")
valueText: mapThrottleFact.value == 0 ? qsTr("Setup required") : qsTr("Channel %1").arg(mapThrottleFact.valueString)
}
}
......
......@@ -34,8 +34,8 @@ SetupPage {
QGCPalette { id: palette; colorGroupEnabled: true }
property Fact _failsafeBattMah: controller.getParameterFact(-1, "FS_BATT_MAH")
property Fact _failsafeBattVoltage: controller.getParameterFact(-1, "FS_BATT_VOLTAGE")
property Fact _failsafeBattMah: controller.getParameterFact(-1, "r.BATT_LOW_MAH")
property Fact _failsafeBattVoltage: controller.getParameterFact(-1, "r.BATT_LOW_VOLT")
property Fact _failsafeThrEnable: controller.getParameterFact(-1, "THR_FAILSAFE")
property Fact _failsafeThrValue: controller.getParameterFact(-1, "THR_FS_VALUE")
property Fact _failsafeGCSEnable: controller.getParameterFact(-1, "FS_GCS_ENABL")
......
......@@ -14,7 +14,7 @@ FactPanel {
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
FactPanelController { id: controller; factPanel: panel }
property Fact _failsafeBattEnable: controller.getParameterFact(-1, "FS_BATT_ENABLE")
property Fact _failsafeBattLowAct: controller.getParameterFact(-1, "r.BATT_FS_LOW_ACT")
property Fact _failsafeThrEnable: controller.getParameterFact(-1, "FS_THR_ENABLE")
property Fact _fenceAction: controller.getParameterFact(-1, "FENCE_ACTION")
......@@ -28,60 +28,14 @@ FactPanel {
property Fact _armingCheck: controller.getParameterFact(-1, "ARMING_CHECK")
property string _failsafeBattEnableText
property string _failsafeThrEnableText
property bool _failsafeBattCritActAvailable: controller.parameterExists(-1, "BATT_FS_CRT_ACT")
property bool _failsafeBatt2LowActAvailable: controller.parameterExists(-1, "BATT2_FS_LOW_ACT")
property bool _failsafeBatt2CritActAvailable: controller.parameterExists(-1, "BATT2_FS_CRT_ACT")
Component.onCompleted: {
setFailsafeBattEnableText()
setFailsafeThrEnableText()
}
Connections {
target: _failsafeBattEnable
onValueChanged: setFailsafeBattEnableText()
}
Connections {
target: _failsafeThrEnable
onValueChanged: setFailsafeThrEnableText()
}
function setFailsafeThrEnableText() {
switch (_failsafeThrEnable.value) {
case 0:
_failsafeThrEnableText = qsTr("Disabled")
break
case 1:
_failsafeThrEnableText = qsTr("Always RTL")
break
case 2:
_failsafeThrEnableText = qsTr("Continue with Mission in Auto Mode")
break
case 3:
_failsafeThrEnableText = qsTr("Always Land")
break
default:
_failsafeThrEnableText = qsTr("Unknown")
}
}
function setFailsafeBattEnableText() {
switch (_failsafeBattEnable.value) {
case 0:
_failsafeBattEnableText = qsTr("Disabled")
break
case 1:
_failsafeBattEnableText = qsTr("Land")
break
case 2:
_failsafeBattEnableText = qsTr("Return to Launch")
break
default:
_failsafeThrEnableText = qsTr("Unknown")
}
}
property Fact _failsafeBattCritAct: controller.getParameterFact(-1, "BATT_FS_CRT_ACT", false /* reportMissing */)
property Fact _batt2Monitor: controller.getParameterFact(-1, "BATT2_MONITOR", false /* reportMissing */)
property Fact _failsafeBatt2LowAct: controller.getParameterFact(-1, "BATT2_FS_LOW_ACT", false /* reportMissing */)
property Fact _failsafeBatt2CritAct: controller.getParameterFact(-1, "BATT2_FS_CRT_ACT", false /* reportMissing */)
Column {
anchors.fill: parent
......@@ -93,12 +47,30 @@ FactPanel {
VehicleSummaryRow {
labelText: qsTr("Throttle failsafe:")
valueText: _failsafeThrEnableText
valueText: _failsafeBattLowAct.enumStringValue
}
VehicleSummaryRow {
labelText: qsTr("Batt low failsafe:")
valueText: _failsafeBattLowAct.enumStringValue
}
VehicleSummaryRow {
labelText: qsTr("Batt critical failsafe:")
valueText: _failsafeBattCritActAvailable ? _failsafeBattCritAct.enumStringValue : ""
visible: _failsafeBattCritActAvailable
}
VehicleSummaryRow {
labelText: qsTr("Batt2 low failsafe:")
valueText: _failsafeBatt2LowActAvailable ? _failsafeBatt2LowAct.enumStringValue : ""
visible: _failsafeBatt2LowActAvailable
}
VehicleSummaryRow {
labelText: qsTr("Battery failsafe:")
valueText: _failsafeBattEnableText
labelText: qsTr("Batt2 critical failsafe:")
valueText: _failsafeBatt2CritActAvailable ? _failsafeBatt2CritAct.enumStringValue : ""
visible: _failsafeBatt2CritActAvailable
}
VehicleSummaryRow {
......
......@@ -34,7 +34,7 @@ FactPanel {
model: 3
VehicleSummaryRow {
labelText: qsTr("Compass ") + (index + 1) + ":"
labelText: qsTr("Compass ") + (index + 1) + ""
valueText: sensorParams.rgCompassAvailable[index] ?
(sensorParams.rgCompassCalibrated[index] ?
(sensorParams.rgCompassPrimary[index] ? "Primary" : "Secondary") +
......@@ -47,7 +47,7 @@ FactPanel {
}
VehicleSummaryRow {
labelText: qsTr("Accelerometer(s):")
labelText: qsTr("Accelerometer(s)")
valueText: controller.accelSetupNeeded ? qsTr("Setup required") : qsTr("Ready")
}
}
......
......@@ -45,17 +45,17 @@ FactPanel {
anchors.fill: parent
VehicleSummaryRow {
id: nameRow;
labelText: qsTr("Frame Type:")
labelText: qsTr("Frame Type")
valueText: frameName()
}
VehicleSummaryRow {
labelText: qsTr("Firmware Version:")
labelText: qsTr("Firmware Version")
valueText: activeVehicle.firmwareMajorVersion == -1 ? qsTr("Unknown") : activeVehicle.firmwareMajorVersion + "." + activeVehicle.firmwareMinorVersion + "." + activeVehicle.firmwarePatchVersion + " " + activeVehicle.firmwareVersionTypeString
}
VehicleSummaryRow {
labelText: qsTr("Git Revision:")
labelText: qsTr("Git Revision")
valueText: activeVehicle.gitHash == -1 ? qsTr("Unknown") : activeVehicle.gitHash
}
}
......
......@@ -39,13 +39,16 @@ SetupPage {
property real _hoverTuneMax: _throttleMidExists ? 800 : 1
property real _hoverTuneStep: _throttleMidExists ? 10 : 0.01
property Fact _rcFeel: controller.getParameterFact(-1, "RC_FEEL_RP")
property Fact _rateRollP: controller.getParameterFact(-1, "r.ATC_RAT_RLL_P")
property Fact _rateRollI: controller.getParameterFact(-1, "r.ATC_RAT_RLL_I")
property Fact _ratePitchP: controller.getParameterFact(-1, "r.ATC_RAT_PIT_P")
property Fact _ratePitchI: controller.getParameterFact(-1, "r.ATC_RAT_PIT_I")
property Fact _rateClimbP: controller.getParameterFact(-1, "ACCEL_Z_P")
property Fact _rateClimbI: controller.getParameterFact(-1, "ACCEL_Z_I")
property bool _rcFeelAvailable: controller.parameterExists(-1, "RC_FEEL")
property bool _atcInputTCAvailable: controller.parameterExists(-1, "ATC_INPUT_TC")
property Fact _rcFeel: controller.getParameterFact(-1, "RC_FEEL", false)
property Fact _atcInputTC: controller.getParameterFact(-1, "ATC_INPUT_TC", false)
property Fact _rateRollP: controller.getParameterFact(-1, "r.ATC_RAT_RLL_P")
property Fact _rateRollI: controller.getParameterFact(-1, "r.ATC_RAT_RLL_I")
property Fact _ratePitchP: controller.getParameterFact(-1, "r.ATC_RAT_PIT_P")
property Fact _ratePitchI: controller.getParameterFact(-1, "r.ATC_RAT_PIT_I")
property Fact _rateClimbP: controller.getParameterFact(-1, "r.PSC_ACCZ_P")
property Fact _rateClimbI: controller.getParameterFact(-1, "r.PSC_ACCZ_I")
property Fact _ch7Opt: controller.getParameterFact(-1, "CH7_OPT")
property Fact _ch8Opt: controller.getParameterFact(-1, "CH8_OPT")
......@@ -78,7 +81,12 @@ SetupPage {
throttleHover.value = _hoverTuneParam.value
rollPitch.value = _rateRollP.value
climb.value = _rateClimbP.value
rcFeel.value = _rcFeel.value
if (_rcFeelAvailable) {
rcFeel.value = _rcFeel.value
}
if (_atcInputTCAvailable) {
atcInputTC.value = _atcInputTC.value
}
_loadComplete = true
calcAutoTuneChannel()
......@@ -240,6 +248,7 @@ SetupPage {
Column {
anchors.left: parent.left
anchors.right: parent.right
visible: _rcFeelAvailable
QGCLabel {
text: qsTr("RC Roll/Pitch Feel")
......@@ -266,6 +275,37 @@ SetupPage {
}
}
}
Column {
anchors.left: parent.left
anchors.right: parent.right
visible: _atcInputTCAvailable
QGCLabel {
text: qsTr("RC Roll/Pitch Feel")
font.family: ScreenTools.demiboldFontFamily
}
QGCLabel {
text: qsTr("Slide to the left for soft control, slide to the right for crisp control")
}
Slider {
id: atcInputTC
anchors.left: parent.left
anchors.right: parent.right
minimumValue: _atcInputTC.min
maximumValue: _atcInputTC.max
stepSize: _atcInputTC.increment
tickmarksEnabled: true
onValueChanged: {
if (_loadComplete) {
_atcInputTC.value = value
}
}
}
}
}
} // Rectangle - Basic tuning
......
......@@ -13,8 +13,6 @@
#include "AutoPilotPlugin.h"
#include "QGCApplication.h"
#include "ParameterManager.h"
#include "UAS.h"
#include "FirmwarePlugin.h"
AutoPilotPlugin::AutoPilotPlugin(Vehicle* vehicle, QObject* parent)
......@@ -28,7 +26,7 @@ AutoPilotPlugin::AutoPilotPlugin(Vehicle* vehicle, QObject* parent)
AutoPilotPlugin::~AutoPilotPlugin()
{
}
void AutoPilotPlugin::_recalcSetupComplete(void)
......
......@@ -19,7 +19,6 @@
#include "FactSystem.h"
#include "Vehicle.h"
class ParameterManager;
class Vehicle;
class FirmwarePlugin;
......
......@@ -30,38 +30,38 @@ FactPanel {
Column {
anchors.fill: parent
VehicleSummaryRow {
labelText: qsTr("Firmware Version:")
labelText: qsTr("Firmware Version")
valueText: esp8266.version
}
VehicleSummaryRow {
labelText: qsTr("WiFi Mode:")
labelText: qsTr("WiFi Mode")
valueText: wifiMode ? (wifiMode.value === 0 ? "AP Mode" : "Station Mode") : "AP Mode"
}
VehicleSummaryRow {
labelText: qsTr("WiFi Channel:")
labelText: qsTr("WiFi Channel")
valueText: wifiChannel ? wifiChannel.valueString : ""
visible: wifiMode ? wifiMode.value === 0 : true
}
VehicleSummaryRow {
labelText: qsTr("WiFi AP SSID:")
labelText: qsTr("WiFi AP SSID")
valueText: esp8266.wifiSSID
}
VehicleSummaryRow {
labelText: qsTr("WiFi AP Password:")
labelText: qsTr("WiFi AP Password")
valueText: esp8266.wifiPassword
}
/* Too much info makes it all crammed
VehicleSummaryRow {
labelText: qsTr("WiFi STA SSID:")
labelText: qsTr("WiFi STA SSID")
valueText: esp8266.wifiSSIDSta
}
VehicleSummaryRow {
labelText: qsTr("WiFi STA Password:")
labelText: qsTr("WiFi STA Password")
valueText: esp8266.wifiPasswordSta
}
*/
VehicleSummaryRow {
labelText: qsTr("UART Baud Rate:")
labelText: qsTr("UART Baud Rate")
valueText: uartBaud ? uartBaud.valueString : ""
}
}
......
......@@ -10,6 +10,7 @@
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.2
import QGroundControl 1.0
import QGroundControl.FactSystem 1.0
......@@ -23,21 +24,26 @@ import QGroundControl.Controllers 1.0
QGCView {
id: setupView
viewPanel: setupPanel
enabled: !_shouldDisableWhenArmed
enabled: !_disableDueToArmed && !_disableDueToFlying
property alias pageComponent: pageLoader.sourceComponent
property string pageName: vehicleComponent ? vehicleComponent.name : ""
property string pageDescription: vehicleComponent ? vehicleComponent.description : ""
property real availableWidth: width - pageLoader.x
property real availableHeight: height - pageLoader.y
property bool showAdvanced: false
property alias advanced: advancedCheckBox.checked
property bool _vehicleArmed: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle.armed : false
property bool _shouldDisableWhenArmed: _vehicleArmed ? (vehicleComponent ? !vehicleComponent.allowSetupWhileArmed : false) : false
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property bool _vehicleArmed: _activeVehicle ? _activeVehicle.armed : false
property bool _vehicleFlying: _activeVehicle ? _activeVehicle.flying : false
property bool _disableDueToArmed: vehicleComponent ? (!vehicleComponent.allowSetupWhileArmed && _vehicleArmed) : false
property bool _disableDueToFlying: vehicleComponent ? (!vehicleComponent.allowSetupWhileFlying && _vehicleFlying) : false
property string _disableReason: _disableDueToArmed ? qsTr("armed") : qsTr("flying")
property real _margins: ScreenTools.defaultFontPixelHeight * 0.5
property string _pageTitle: qsTr("%1 Setup").arg(pageName)
QGCPalette { id: qgcPal; colorGroupEnabled: setupPanel.enabled }
QGCViewPanel {
......@@ -50,35 +56,49 @@ QGCView {
contentHeight: pageLoader.y + pageLoader.item.height
clip: true
Column {
id: headingColumn
width: setupPanel.width
RowLayout {
id: headingRow
anchors.left: parent.left
anchors.right: parent.right
spacing: _margins
layoutDirection: Qt.RightToLeft
QGCLabel {
font.pointSize: ScreenTools.largeFontPointSize
text: _shouldDisableWhenArmed ? _pageTitle + "<font color=\"red\">" + qsTr(" (Disabled while the vehicle is armed)") + "</font>" : _pageTitle
visible: !ScreenTools.isShortScreen
QGCCheckBox {
id: advancedCheckBox
text: qsTr("Advanced")
visible: showAdvanced
}
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: pageDescription
visible: !ScreenTools.isShortScreen
Column {
spacing: _margins
Layout.fillWidth: true
QGCLabel {
font.pointSize: ScreenTools.largeFontPointSize
text: !setupView.enabled ? _pageTitle + "<font color=\"red\">" + qsTr(" (Disabled while the vehicle is %1)").arg(_disableReason) + "</font>" : _pageTitle
visible: !ScreenTools.isShortScreen
}
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: pageDescription
visible: !ScreenTools.isShortScreen
}
}
}
Loader {
id: pageLoader
anchors.topMargin: _margins
anchors.top: headingColumn.bottom
anchors.top: headingRow.bottom
}
// Overlay to display when vehicle is armed and this setup page needs
// to be disabled
Rectangle {
visible: _shouldDisableWhenArmed
visible: !setupView.enabled
anchors.fill: pageLoader
color: "black"
opacity: 0.5
......
......@@ -23,20 +23,20 @@ FactPanel {
Column {
anchors.fill: parent
VehicleSummaryRow {
labelText: qsTr("System ID:")
labelText: qsTr("System ID")
valueText: sysIdFact ? sysIdFact.valueString : ""
}
VehicleSummaryRow {
labelText: qsTr("Airframe type:")
labelText: qsTr("Airframe type")
valueText: autoStartSet ? controller.currentAirframeType : qsTr("Setup required")
}
VehicleSummaryRow {
labelText: qsTr("Vehicle:")
labelText: qsTr("Vehicle")
valueText: autoStartSet ? controller.currentVehicleName : qsTr("Setup required")
}
VehicleSummaryRow {
labelText: qsTr("Firmware Version:")
labelText: qsTr("Firmware Version")
valueText: activeVehicle.firmwareMajorVersion === -1 ? qsTr("Unknown") : activeVehicle.firmwareMajorVersion + "." + activeVehicle.firmwareMinorVersion + "." + activeVehicle.firmwarePatchVersion + activeVehicle.firmwareVersionTypeString
}
}
......
......@@ -329,6 +329,11 @@
<maintainer>Michael Schaeuble</maintainer>
<type>Quadrotor x</type>
</airframe>
<airframe id="4014" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="S500">
<class>Copter</class>
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Quadrotor x</type>
</airframe>
<airframe id="4020" maintainer="Thomas Gubler &lt;thomas@px4.io&gt;" name="Hobbyking Micro PCB">
<class>Copter</class>
<maintainer>Thomas Gubler &lt;thomas@px4.io&gt;</maintainer>
......
......@@ -121,14 +121,14 @@ SetupPage {
}
QGCLabel {
anchors.baseline: camTrigCombo.baseline
Layout.alignment: Qt.AlignVCenter
text: qsTr("Trigger mode")
}
FactComboBox {
id: camTrigCombo
fact: _camTriggerMode
indexModel: false
enabled: !_rebooting
Layout.alignment: Qt.AlignVCenter
Layout.minimumWidth: _editFieldWidth
onActivated: {
applyAndRestart.visible = true
......@@ -136,14 +136,14 @@ SetupPage {
}
QGCLabel {
anchors.baseline: camInterfaceCombo.baseline
Layout.alignment: Qt.AlignVCenter
text: qsTr("Trigger interface")
}
FactComboBox {
id: camInterfaceCombo
fact: _camTriggerInterface
indexModel: false
enabled: !_rebooting && (_camTriggerInterface ? true : false)
Layout.alignment: Qt.AlignVCenter
Layout.minimumWidth: _editFieldWidth
onActivated: {
applyAndRestart.visible = true
......@@ -152,7 +152,7 @@ SetupPage {
QGCLabel {
text: qsTr("Time Interval")
anchors.baseline: timeIntervalField.baseline
Layout.alignment: Qt.AlignVCenter
color: qgcPal.text
visible: timeIntervalField.visible
}
......@@ -161,12 +161,13 @@ SetupPage {
fact: controller.getParameterFact(-1, "TRIG_INTERVAL", false)
showUnits: true
Layout.minimumWidth: _editFieldWidth
Layout.alignment: Qt.AlignVCenter
visible: _camTriggerMode.value === 2
}
QGCLabel {
text: qsTr("Distance Interval")
anchors.baseline: trigDistField.baseline
Layout.alignment: Qt.AlignVCenter
color: qgcPal.text
visible: trigDistField.visible
}
......@@ -174,6 +175,7 @@ SetupPage {
id: trigDistField
fact: controller.getParameterFact(-1, "TRIG_DISTANCE", false)
showUnits: true
Layout.alignment: Qt.AlignVCenter
Layout.minimumWidth: _editFieldWidth
visible: _camTriggerMode.value === 3
}
......@@ -199,8 +201,8 @@ SetupPage {
}
Row {
spacing: _margins
anchors.horizontalCenter: parent.horizontalCenter
spacing: _margins
Layout.alignment: Qt.AlignHCenter
GridLayout {
rows: 2
......
......@@ -25,36 +25,36 @@ FactPanel {
anchors.fill: parent
VehicleSummaryRow {
labelText: qsTr("Trigger interface:")
labelText: qsTr("Trigger interface")
valueText: _camTriggerInterface ? _camTriggerInterface.enumStringValue : ""
}
VehicleSummaryRow {
labelText: qsTr("Trigger mode:")
labelText: qsTr("Trigger mode")
valueText: _camTriggerMode ? _camTriggerMode.enumStringValue : ""
}
VehicleSummaryRow {
visible: _timeInterval && _camTriggerMode.value === 2
labelText: qsTr("Time interval:")
labelText: qsTr("Time interval")
valueText: _timeInterval ? _timeInterval.value : ""
}
VehicleSummaryRow {
visible: _distanceInterval && _camTriggerMode.value === 3
labelText: qsTr("Distance interval:")
labelText: qsTr("Distance interval")
valueText: _distanceInterval ? _distanceInterval.value : ""
}
VehicleSummaryRow {
visible: _auxPins
labelText: qsTr("AUX pins:")
labelText: qsTr("AUX pins")
valueText: _auxPins ? _auxPins.value : ""
}
VehicleSummaryRow {
visible: _camTriggerPol
labelText: qsTr("AUX pin polarity:")
labelText: qsTr("AUX pin polarity")
valueText: _camTriggerPol ? (_camTriggerPol.value ? "High (3.3V)" : "Low (0V)") : ""
}
......
......@@ -29,13 +29,13 @@ FactPanel {
id: simple
Column {
VehicleSummaryRow {
labelText: qsTr("Mode switch:")
labelText: qsTr("Mode switch")
valueText: _rcMapFltmode.value === 0 ? qsTr("Setup required") : _rcMapFltmode.enumStringValue
}
Repeater {
model: 6
VehicleSummaryRow {
labelText: qsTr("Flight Mode %1 :").arg(index + 1)
labelText: qsTr("Flight Mode %1 ").arg(index + 1)
valueText: controller.getParameterFact(-1, "COM_FLTMODE" + (index + 1)).enumStringValue
}
}
......@@ -49,19 +49,19 @@ FactPanel {
property Fact loiterSwFact: controller.getParameterFact(-1, "RC_MAP_LOITER_SW")
property Fact returnSwFact: controller.getParameterFact(-1, "RC_MAP_RETURN_SW")
VehicleSummaryRow {
labelText: qsTr("Mode switch:")
labelText: qsTr("Mode switch")
valueText: _rcMapModeSw.value === 0 ? qsTr("Setup required") : _rcMapModeSw.valueString
}
VehicleSummaryRow {
labelText: qsTr("Position Ctl switch:")
labelText: qsTr("Position Ctl switch")
valueText: posCtlSwFact.value === 0 ? qsTr("Disabled") : posCtlSwFact.valueString
}
VehicleSummaryRow {
labelText: qsTr("Loiter switch:")
labelText: qsTr("Loiter switch")
valueText: loiterSwFact.value === 0 ? qsTr("Disabled") : loiterSwFact.valueString
}
VehicleSummaryRow {
labelText: qsTr("Return switch:")
labelText: qsTr("Return switch")
valueText: returnSwFact.value === 0 ? qsTr("Disabled") : returnSwFact.valueString
}
}
......
......@@ -26,38 +26,38 @@ FactPanel {
anchors.fill: parent
VehicleSummaryRow {
labelText: qsTr("Roll:")
labelText: qsTr("Roll")
valueText: mapRollFact ? (mapRollFact.value === 0 ? qsTr("Setup required") : mapRollFact.valueString) : ""
}
VehicleSummaryRow {
labelText: qsTr("Pitch:")
labelText: qsTr("Pitch")
valueText: mapPitchFact ? (mapPitchFact.value === 0 ? qsTr("Setup required") : mapPitchFact.valueString) : ""
}
VehicleSummaryRow {
labelText: qsTr("Yaw:")
labelText: qsTr("Yaw")
valueText: mapYawFact ? (mapYawFact.value === 0 ? qsTr("Setup required") : mapYawFact.valueString) : ""
}
VehicleSummaryRow {
labelText: qsTr("Throttle:")
labelText: qsTr("Throttle")
valueText: mapThrottleFact ? (mapThrottleFact.value === 0 ? qsTr("Setup required") : mapThrottleFact.valueString) : ""
}
VehicleSummaryRow {
labelText: qsTr("Flaps:")
labelText: qsTr("Flaps")
valueText: mapFlapsFact ? (mapFlapsFact.value === 0 ? qsTr("Disabled") : mapFlapsFact.valueString) : ""
visible: !controller.vehicle.multiRotor
}
VehicleSummaryRow {
labelText: qsTr("Aux1:")
labelText: qsTr("Aux1")
valueText: mapAux1Fact ? (mapAux1Fact.value === 0 ? qsTr("Disabled") : mapAux1Fact.valueString) : ""
}
VehicleSummaryRow {
labelText: qsTr("Aux2:")
labelText: qsTr("Aux2")
valueText: mapAux2Fact ? (mapAux2Fact.value === 0 ? qsTr("Disabled") : mapAux2Fact.valueString) : ""
}
}
......
......@@ -32,6 +32,7 @@ public:
QUrl setupSource(void) const final;
QUrl summaryQmlSource(void) const final;
bool allowSetupWhileArmed(void) const final { return true; }
bool allowSetupWhileFlying(void) const final { return true; }
private:
const QString _name;
......
......@@ -7,11 +7,16 @@
*
****************************************************************************/
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtCharts 2.2
import QtQuick.Layouts 1.2
import QtQuick 2.3
import QtQuick.Controls 1.2
import QGroundControl.Controls 1.0
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.ScreenTools 1.0
SetupPage {
id: tuningPage
......@@ -20,47 +25,97 @@ SetupPage {
Component {
id: pageComponent
FactSliderPanel {
width: availableWidth
qgcViewPanel: tuningPage.viewPanel
Column {
width: availableWidth
sliderModel: ListModel {
ListElement {
title: qsTr("Hover Throttle")
description: qsTr("Adjust throttle so hover is at mid-throttle. Slide to the left if hover is lower than throttle center. Slide to the right if hover is higher than throttle center.")
param: "MPC_THR_HOVER"
min: 20
max: 80
step: 1
}
Component.onCompleted: {
showAdvanced = !ScreenTools.isMobile
}
ListElement {
title: qsTr("Manual minimum throttle")
description: qsTr("Slide to the left to start the motors with less idle power. Slide to the right if descending in manual flight becomes unstable.")
param: "MPC_MANTHR_MIN"
min: 0
max: 15
step: 1
}
FactPanelController {
id: controller
factPanel: tuningPage.viewPanel
}
ListElement {
title: qsTr("Roll sensitivity")
description: qsTr("Slide to the left to make roll control faster and more accurate. Slide to the right if roll oscillates or is too twitchy.")
param: "MC_ROLL_TC"
min: 0.15
max: 0.25
step: 0.01
}
// Standard tuning page
FactSliderPanel {
width: availableWidth
qgcViewPanel: tuningPage.viewPanel
visible: !advanced
sliderModel: ListModel {
ListElement {
title: qsTr("Hover Throttle")
description: qsTr("Adjust throttle so hover is at mid-throttle. Slide to the left if hover is lower than throttle center. Slide to the right if hover is higher than throttle center.")
param: "MPC_THR_HOVER"
min: 20
max: 80
step: 1
}
ListElement {
title: qsTr("Pitch sensitivity")
description: qsTr("Slide to the left to make pitch control faster and more accurate. Slide to the right if pitch oscillates or is too twitchy.")
param: "MC_PITCH_TC"
min: 0.15
max: 0.25
step: 0.01
ListElement {
title: qsTr("Manual minimum throttle")
description: qsTr("Slide to the left to start the motors with less idle power. Slide to the right if descending in manual flight becomes unstable.")
param: "MPC_MANTHR_MIN"
min: 0
max: 15
step: 1
}
/*
These seem to have disappeared from PX4 firmware!
ListElement {
title: qsTr("Roll sensitivity")
description: qsTr("Slide to the left to make roll control faster and more accurate. Slide to the right if roll oscillates or is too twitchy.")
param: "MC_ROLL_TC"
min: 0.15
max: 0.25
step: 0.01
}
ListElement {
title: qsTr("Pitch sensitivity")
description: qsTr("Slide to the left to make pitch control faster and more accurate. Slide to the right if pitch oscillates or is too twitchy.")
param: "MC_PITCH_TC"
min: 0.15
max: 0.25
step: 0.01
}
*/
}
}
}
} // Component
Loader {
anchors.left: parent.left
anchors.right: parent.right
sourceComponent: advanced ? advancePageComponent : undefined
}
Component {
id: advancePageComponent
PIDTuning {
anchors.left: parent.left
anchors.right: parent.right
tuneList: [ qsTr("Roll"), qsTr("Pitch"), qsTr("Yaw") ]
params: [
[ controller.getParameterFact(-1, "MC_ROLL_P"),
controller.getParameterFact(-1, "MC_ROLLRATE_P"),
controller.getParameterFact(-1, "MC_ROLLRATE_I"),
controller.getParameterFact(-1, "MC_ROLLRATE_D"),
controller.getParameterFact(-1, "MC_ROLLRATE_FF") ],
[ controller.getParameterFact(-1, "MC_PITCH_P"),
controller.getParameterFact(-1, "MC_PITCHRATE_P"),
controller.getParameterFact(-1, "MC_PITCHRATE_I"),
controller.getParameterFact(-1, "MC_PITCHRATE_D"),
controller.getParameterFact(-1, "MC_PITCHRATE_FF") ],
[ controller.getParameterFact(-1, "MC_YAW_P"),
controller.getParameterFact(-1, "MC_YAWRATE_P"),
controller.getParameterFact(-1, "MC_YAWRATE_I"),
controller.getParameterFact(-1, "MC_YAWRATE_D"),
controller.getParameterFact(-1, "MC_YAW_FF"),
controller.getParameterFact(-1, "MC_YAWRATE_FF") ] ]
}
} // Component - Advanced Page
} // Column
} // Component - pageComponent
} // SetupPage
......@@ -7,11 +7,16 @@
*
****************************************************************************/
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtCharts 2.2
import QtQuick.Layouts 1.2
import QtQuick 2.3
import QtQuick.Controls 1.2
import QGroundControl.Controls 1.0
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.ScreenTools 1.0
SetupPage {
id: tuningPage
......@@ -20,47 +25,64 @@ SetupPage {
Component {
id: pageComponent
FactSliderPanel {
width: availableWidth
qgcViewPanel: tuningPage.viewPanel
Column {
width: availableWidth
sliderModel: ListModel {
ListElement {
title: qsTr("Roll sensitivity")
description: qsTr("Slide to the left to make roll control faster and more accurate. Slide to the right if roll oscillates or is too twitchy.")
param: "FW_R_TC"
min: 0.2
max: 0.8
step: 0.01
}
Component.onCompleted: {
showAdvanced = !ScreenTools.isMobile
}
ListElement {
title: qsTr("Pitch sensitivity")
description: qsTr("Slide to the left to make pitch control faster and more accurate. Slide to the right if pitch oscillates or is too twitchy.")
param: "FW_P_TC"
min: 0.2
max: 0.8
step: 0.01
}
FactPanelController {
id: controller
factPanel: tuningPage.viewPanel
}
ListElement {
title: qsTr("Cruise throttle")
description: qsTr("This is the throttle setting required to achieve the desired cruise speed. Most planes need 50-60%.")
param: "FW_THR_CRUISE"
min: 20
max: 80
step: 1
}
// Standard tuning page
FactSliderPanel {
width: availableWidth
qgcViewPanel: tuningPage.viewPanel
visible: !advanced
ListElement {
title: qsTr("Mission mode sensitivity")
description: qsTr("Slide to the left to make position control more accurate and more aggressive. Slide to the right to make flight in mission mode smoother and less twitchy.")
param: "FW_L1_PERIOD"
min: 12
max: 50
step: 0.5
sliderModel: ListModel {
ListElement {
title: qsTr("Cruise throttle")
description: qsTr("This is the throttle setting required to achieve the desired cruise speed. Most planes need 50-60%.")
param: "FW_THR_CRUISE"
min: 20
max: 80
step: 1
}
}
}
}
}
}
Loader {
anchors.left: parent.left
anchors.right: parent.right
sourceComponent: advanced ? advancePageComponent : undefined
}
Component {
id: advancePageComponent
PIDTuning {
anchors.left: parent.left
anchors.right: parent.right
tuneList: [ qsTr("Roll"), qsTr("Pitch"), qsTr("Yaw") ]
params: [
[ controller.getParameterFact(-1, "FW_RR_P"),
controller.getParameterFact(-1, "FW_RR_I"),
controller.getParameterFact(-1, "FW_RR_FF"),
controller.getParameterFact(-1, "FW_R_TC"),],
[ controller.getParameterFact(-1, "FW_PR_P"),
controller.getParameterFact(-1, "FW_PR_I"),
controller.getParameterFact(-1, "FW_PR_FF"),
controller.getParameterFact(-1, "FW_P_TC") ],
[ controller.getParameterFact(-1, "FW_YR_P"),
controller.getParameterFact(-1, "FW_YR_I"),
controller.getParameterFact(-1, "FW_YR_FF") ] ]
}
} // Component - Advanced Page
} // Column
} // Component - pageComponent
} // SetupPage
......@@ -26,24 +26,6 @@ SetupPage {
sliderModel: ListModel {
ListElement {
title: qsTr("Hover Roll sensitivity")
description: qsTr("Slide to the left to make roll control during hover faster and more accurate. Slide to the right if roll oscillates or is too twitchy.")
param: "MC_ROLL_TC"
min: 0.15
max: 0.25
step: 0.01
}
ListElement {
title: qsTr("Hover Pitch sensitivity")
description: qsTr("Slide to the left to make pitch control during hover faster and more accurate. Slide to the right if pitch oscillates or is too twitchy.")
param: "MC_PITCH_TC"
min: 0.15
max: 0.25
step: 0.01
}
ListElement {
title: qsTr("Plane Roll sensitivity")
description: qsTr("Slide to the left to make roll control faster and more accurate. Slide to the right if roll oscillates or is too twitchy.")
......@@ -81,7 +63,7 @@ SetupPage {
}
ListElement {
title: qsTr("Hoever manual minimum throttle")
title: qsTr("Hover manual minimum throttle")
description: qsTr("Slide to the left to start the motors with less idle power. Slide to the right if descending in manual flight becomes unstable.")
param: "MPC_MANTHR_MIN"
min: 0
......
......@@ -24,18 +24,19 @@ class PowerComponent : public VehicleComponent
public:
PowerComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent = NULL);
// Virtuals from VehicleComponent
virtual QStringList setupCompleteChangedTriggerList(void) const;
// Virtuals from VehicleComponent
virtual QString name (void) const;
virtual QString description (void) const;
virtual QString iconResource (void) const;
virtual bool requiresSetup (void) const;
virtual bool setupComplete (void) const;
virtual QUrl setupSource (void) const;
virtual QUrl summaryQmlSource (void) const;
// Overrides from VehicleComponent
QStringList setupCompleteChangedTriggerList(void) const override;
// Overrides from VehicleComponent
QString name (void) const override;
QString description (void) const override;
QString iconResource (void) const override;
bool requiresSetup (void) const override;
bool setupComplete (void) const override;
QUrl setupSource (void) const override;
QUrl summaryQmlSource (void) const override;
bool allowSetupWhileArmed (void) const override { return true; }
private:
const QString _name;
QVariantList _summaryItems;
......
......@@ -348,9 +348,9 @@ SetupPage {
} // QGCGroupBox - Battery settings
QGCGroupBox {
anchors.left: batteryGroup.left
anchors.right: batteryGroup.right
title: qsTr("ESC PWM Minimum and Maximum Calibration")
Layout.maximumWidth: batteryGroup.width
Layout.fillWidth: true
title: qsTr("ESC PWM Minimum and Maximum Calibration")
ColumnLayout {
anchors.left: parent.left
......@@ -383,10 +383,10 @@ SetupPage {
}
QGCGroupBox {
anchors.left: batteryGroup.left
anchors.right: batteryGroup.right
title: qsTr("UAVCAN Bus Configuration")
visible: showUAVCAN.checked
Layout.maximumWidth: batteryGroup.width
Layout.fillWidth: true
title: qsTr("UAVCAN Bus Configuration")
visible: showUAVCAN.checked
Row {
id: uavCanConfigRow
......@@ -407,10 +407,10 @@ SetupPage {
}
QGCGroupBox {
anchors.left: batteryGroup.left
anchors.right: batteryGroup.right
title: qsTr("UAVCAN Motor Index and Direction Assignment")
visible: showUAVCAN.checked
Layout.maximumWidth: batteryGroup.width
Layout.fillWidth: true
title: qsTr("UAVCAN Motor Index and Direction Assignment")
visible: showUAVCAN.checked
ColumnLayout {
anchors.left: parent.left
......@@ -456,10 +456,10 @@ SetupPage {
}
QGCGroupBox {
anchors.left: batteryGroup.left
anchors.right: batteryGroup.right
title: qsTr("Advanced Power Settings")
visible: showAdvanced.checked
Layout.maximumWidth: batteryGroup.width
Layout.fillWidth: true
title: qsTr("Advanced Power Settings")
visible: showAdvanced.checked
ColumnLayout {
anchors.left: parent.left
......@@ -487,7 +487,7 @@ SetupPage {
text: qsTr("Batteries show less voltage at high throttle. Enter the difference in Volts between idle throttle and full ") +
qsTr("throttle, divided by the number of battery cells. Leave at the default if unsure. ") +
highlightPrefix + qsTr("If this value is set too high, the battery might be deep discharged and damaged.") + highlightSuffix
Layout.fillWidth: true
Layout.maximumWidth: ScreenTools.defaultFontPixelWidth * 60
}
Row {
......
......@@ -36,17 +36,17 @@ FactPanel {
anchors.fill: parent
VehicleSummaryRow {
labelText: qsTr("Battery Full:")
labelText: qsTr("Battery Full")
valueText: batVChargedFact ? batVChargedFact.valueString + " " + batVChargedFact.units : ""
}
VehicleSummaryRow {
labelText: qsTr("Battery Empty:")
labelText: qsTr("Battery Empty")
valueText: batVEmptyFact ? batVEmptyFact.valueString + " " + batVEmptyFact.units : ""
}
VehicleSummaryRow {
labelText: qsTr("Number of Cells:")
labelText: qsTr("Number of Cells")
valueText: batCellsFact ? batCellsFact.valueString : ""
}
}
......
......@@ -14,46 +14,64 @@ FactPanel {
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
FactPanelController { id: controller; factPanel: panel }
property Fact returnAltFact: controller.getParameterFact(-1, "RTL_RETURN_ALT")
property Fact descendAltFact: controller.getParameterFact(-1, "RTL_DESCEND_ALT")
property Fact landDelayFact: controller.getParameterFact(-1, "RTL_LAND_DELAY")
property Fact commRCLossFact: controller.getParameterFact(-1, "COM_RC_LOSS_T")
property Fact lowBattAction: controller.getParameterFact(-1, "COM_LOW_BAT_ACT")
property Fact rcLossAction: controller.getParameterFact(-1, "NAV_RCL_ACT")
property Fact dataLossAction: controller.getParameterFact(-1, "NAV_DLL_ACT")
property Fact returnAltFact: controller.getParameterFact(-1, "RTL_RETURN_ALT")
property Fact _descendAltFact: controller.getParameterFact(-1, "RTL_DESCEND_ALT")
property Fact landDelayFact: controller.getParameterFact(-1, "RTL_LAND_DELAY")
property Fact commRCLossFact: controller.getParameterFact(-1, "COM_RC_LOSS_T")
property Fact lowBattAction: controller.getParameterFact(-1, "COM_LOW_BAT_ACT")
property Fact rcLossAction: controller.getParameterFact(-1, "NAV_RCL_ACT")
property Fact dataLossAction: controller.getParameterFact(-1, "NAV_DLL_ACT")
property Fact _rtlLandDelayFact: controller.getParameterFact(-1, "RTL_LAND_DELAY")
property int _rtlLandDelayValue: _rtlLandDelayFact.value
Column {
anchors.fill: parent
VehicleSummaryRow {
labelText: qsTr("RTL min alt:")
valueText: returnAltFact ? returnAltFact.valueString + " " + returnAltFact.units : ""
labelText: qsTr("Low Battery Failsafe")
valueText: lowBattAction ? lowBattAction.enumStringValue : ""
}
VehicleSummaryRow {
labelText: qsTr("RTL home alt:")
valueText: descendAltFact ? descendAltFact.valueString + " " + descendAltFact.units : ""
labelText: qsTr("RC Loss Failsafe")
valueText: rcLossAction ? rcLossAction.enumStringValue : ""
}
VehicleSummaryRow {
labelText: qsTr("RC loss RTL:")
labelText: qsTr("RC Loss Timeout")
valueText: commRCLossFact ? commRCLossFact.valueString + " " + commRCLossFact.units : ""
}
VehicleSummaryRow {
labelText: qsTr("RC loss action:")
valueText: rcLossAction ? rcLossAction.enumStringValue : ""
labelText: qsTr("Data Link Loss Failsafe")
valueText: dataLossAction ? dataLossAction.enumStringValue : ""
}
VehicleSummaryRow {
labelText: qsTr("Link loss action:")
valueText: dataLossAction ? dataLossAction.enumStringValue : ""
labelText: qsTr("RTL Climb To")
valueText: returnAltFact ? returnAltFact.valueString + " " + returnAltFact.units : ""
}
VehicleSummaryRow {
labelText: qsTr("Low battery action:")
valueText: lowBattAction ? lowBattAction.enumStringValue : ""
labelText: qsTr("RTL, Then")
valueText: _rtlLandDelayValue === 0 ?
qsTr("Land immediately") :
(_rtlLandDelayValue < 0 ?
qsTr("Loiter and do not land") :
qsTr("Loiter and land after specified time"))
}
VehicleSummaryRow {
labelText: qsTr("Loiter Alt")
valueText: _descendAltFact.valueString + " " + _descendAltFact.units
visible: _rtlLandDelayValue !== 0
}
VehicleSummaryRow {
labelText: qsTr("Land Delay")
valueText: _rtlLandDelayValue + " " + _rtlLandDelayFact.units
visible: _rtlLandDelayValue > 0
}
}
}
......@@ -20,11 +20,14 @@ const char* SensorsComponent::_airspeedBreakerParam = "CBRK_AIRSPD_CHK";
const char* SensorsComponent::_airspeedDisabledParam = "FW_ARSP_MODE";
const char* SensorsComponent::_airspeedCalParam = "SENS_DPRES_OFF";
const char* SensorsComponent::_magEnabledParam = "SYS_HAS_MAG";
const char* SensorsComponent::_magCalParam = "CAL_MAG0_ID";
SensorsComponent::SensorsComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) :
VehicleComponent(vehicle, autopilot, parent),
_name(tr("Sensors"))
{
_deviceIds << QStringLiteral("CAL_MAG0_ID") << QStringLiteral("CAL_GYRO0_ID") << QStringLiteral("CAL_ACC0_ID");
_deviceIds << QStringLiteral("CAL_GYRO0_ID") << QStringLiteral("CAL_ACC0_ID");
}
QString SensorsComponent::name(void) const
......@@ -54,6 +57,14 @@ bool SensorsComponent::setupComplete(void) const
return false;
}
}
bool magEnabled = true;
if (_vehicle->parameterManager()->parameterExists(FactSystem::defaultComponentId, _magEnabledParam)) {
magEnabled = _vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, _magEnabledParam)->rawValue().toBool();
}
if (magEnabled && _vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, _magCalParam)->rawValue().toFloat() == 0.0f) {
return false;
}
if (_vehicle->fixedWing() || _vehicle->vtol()) {
if (!_vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, _airspeedDisabledParam)->rawValue().toBool() &&
......@@ -70,7 +81,7 @@ QStringList SensorsComponent::setupCompleteChangedTriggerList(void) const
{
QStringList triggers;
triggers << _deviceIds;
triggers << _deviceIds << _magCalParam << _magEnabledParam;
if (_vehicle->fixedWing() || _vehicle->vtol()) {
triggers << _airspeedCalParam << _airspeedBreakerParam;
}
......
......@@ -44,6 +44,9 @@ private:
static const char* _airspeedDisabledParam;
static const char* _airspeedBreakerParam;
static const char* _airspeedCalParam;
static const char* _magEnabledParam;
static const char* _magCalParam;
};
#endif
......@@ -7,10 +7,6 @@
*
****************************************************************************/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "SensorsComponentController.h"
#include "QGCMAVLink.h"
#include "UAS.h"
......@@ -22,46 +18,48 @@
QGC_LOGGING_CATEGORY(SensorsComponentControllerLog, "SensorsComponentControllerLog")
SensorsComponentController::SensorsComponentController(void) :
_statusLog(NULL),
_progressBar(NULL),
_compassButton(NULL),
_gyroButton(NULL),
_accelButton(NULL),
_airspeedButton(NULL),
_levelButton(NULL),
_cancelButton(NULL),
_setOrientationsButton(NULL),
_showOrientationCalArea(false),
_gyroCalInProgress(false),
_magCalInProgress(false),
_accelCalInProgress(false),
_orientationCalDownSideDone(false),
_orientationCalUpsideDownSideDone(false),
_orientationCalLeftSideDone(false),
_orientationCalRightSideDone(false),
_orientationCalNoseDownSideDone(false),
_orientationCalTailDownSideDone(false),
_orientationCalDownSideVisible(false),
_orientationCalUpsideDownSideVisible(false),
_orientationCalLeftSideVisible(false),
_orientationCalRightSideVisible(false),
_orientationCalNoseDownSideVisible(false),
_orientationCalTailDownSideVisible(false),
_orientationCalDownSideInProgress(false),
_orientationCalUpsideDownSideInProgress(false),
_orientationCalLeftSideInProgress(false),
_orientationCalRightSideInProgress(false),
_orientationCalNoseDownSideInProgress(false),
_orientationCalTailDownSideInProgress(false),
_orientationCalDownSideRotate(false),
_orientationCalUpsideDownSideRotate(false),
_orientationCalLeftSideRotate(false),
_orientationCalRightSideRotate(false),
_orientationCalNoseDownSideRotate(false),
_orientationCalTailDownSideRotate(false),
_unknownFirmwareVersion(false),
_waitingForCancel(false)
SensorsComponentController::SensorsComponentController(void)
: _statusLog (NULL)
, _progressBar (NULL)
, _compassButton (NULL)
, _gyroButton (NULL)
, _accelButton (NULL)
, _airspeedButton (NULL)
, _levelButton (NULL)
, _cancelButton (NULL)
, _setOrientationsButton (NULL)
, _showOrientationCalArea (false)
, _gyroCalInProgress (false)
, _magCalInProgress (false)
, _accelCalInProgress (false)
, _airspeedCalInProgress (false)
, _levelCalInProgress (false)
, _orientationCalDownSideDone (false)
, _orientationCalUpsideDownSideDone (false)
, _orientationCalLeftSideDone (false)
, _orientationCalRightSideDone (false)
, _orientationCalNoseDownSideDone (false)
, _orientationCalTailDownSideDone (false)
, _orientationCalDownSideVisible (false)
, _orientationCalUpsideDownSideVisible (false)
, _orientationCalLeftSideVisible (false)
, _orientationCalRightSideVisible (false)
, _orientationCalNoseDownSideVisible (false)
, _orientationCalTailDownSideVisible (false)
, _orientationCalDownSideInProgress (false)
, _orientationCalUpsideDownSideInProgress (false)
, _orientationCalLeftSideInProgress (false)
, _orientationCalRightSideInProgress (false)
, _orientationCalNoseDownSideInProgress (false)
, _orientationCalTailDownSideInProgress (false)
, _orientationCalDownSideRotate (false)
, _orientationCalUpsideDownSideRotate (false)
, _orientationCalLeftSideRotate (false)
, _orientationCalRightSideRotate (false)
, _orientationCalNoseDownSideRotate (false)
, _orientationCalTailDownSideRotate (false)
, _unknownFirmwareVersion (false)
, _waitingForCancel (false)
{
}
......@@ -165,7 +163,9 @@ void SensorsComponentController::_stopCalibration(SensorsComponentController::St
switch (code) {
case StopCalibrationSuccess:
_orientationCalAreaHelpText->setProperty("text", tr("Calibration complete"));
emit resetStatusTextArea();
if (!_airspeedCalInProgress && !_levelCalInProgress) {
emit resetStatusTextArea();
}
if (_magCalInProgress) {
emit setCompassRotations();
}
......@@ -186,6 +186,7 @@ void SensorsComponentController::_stopCalibration(SensorsComponentController::St
_magCalInProgress = false;
_accelCalInProgress = false;
_gyroCalInProgress = false;
_airspeedCalInProgress = false;
}
void SensorsComponentController::calibrateGyro(void)
......@@ -336,6 +337,10 @@ void SensorsComponentController::_handleUASTextMessage(int uasId, int compId, in
emit orientationCalSidesVisibleChanged();
emit orientationCalSidesInProgressChanged();
_updateAndEmitShowOrientationCalArea(true);
} else if (text == "airspeed") {
_airspeedCalInProgress = true;
} else if (text == "level") {
_levelCalInProgress = true;
}
return;
}
......
......@@ -131,7 +131,9 @@ private:
bool _gyroCalInProgress;
bool _magCalInProgress;
bool _accelCalInProgress;
bool _airspeedCalInProgress;
bool _levelCalInProgress;
bool _orientationCalDownSideDone;
bool _orientationCalUpsideDownSideDone;
bool _orientationCalLeftSideDone;
......
......@@ -29,29 +29,29 @@ FactPanel {
anchors.fill: parent
VehicleSummaryRow {
labelText: qsTr("Compass 0:")
labelText: qsTr("Compass 0")
valueText: mag0IdFact ? (mag0IdFact.value === 0 ? qsTr("Setup required") : qsTr("Ready")) : ""
}
VehicleSummaryRow {
labelText: qsTr("Compass 1:")
labelText: qsTr("Compass 1")
visible: mag1IdFact.value !== 0
valueText: qsTr("Ready")
}
VehicleSummaryRow {
labelText: qsTr("Compass 2:")
labelText: qsTr("Compass 2")
visible: mag2IdFact.value !== 0
valueText: qsTr("Ready")
}
VehicleSummaryRow {
labelText: qsTr("Gyro:")
labelText: qsTr("Gyro")
valueText: gyro0IdFact ? (gyro0IdFact.value === 0 ? qsTr("Setup required") : qsTr("Ready")) : ""
}
VehicleSummaryRow {
labelText: qsTr("Accelerometer:")
labelText: qsTr("Accelerometer")
valueText: accel0IdFact ? (accel0IdFact.value === 0 ? qsTr("Setup required") : qsTr("Ready")) : ""
}
}
......
......@@ -25,7 +25,7 @@ FactPanel {
property Fact airspeedDisabledFact: controller.getParameterFact(-1, "FW_ARSP_MODE")
property Fact airspeedBreakerFact: controller.getParameterFact(-1, "CBRK_AIRSPD_CHK")
property bool _airspeedVisible: airspeedDisabledFact.value === false && airspeedBreakerFact.value !== 162128
property bool _airspeedVisible: airspeedDisabledFact.value == 0 && airspeedBreakerFact.value !== 162128
property bool _airspeedCalRequired: _airspeedVisible && dpressOffFact.value === 0
Column {
......
......@@ -140,9 +140,7 @@ Item {
onWaitingForCancelChanged: {
if (controller.waitingForCancel) {
showMessage(qsTr("Calibration Cancel"), qsTr("Waiting for Vehicle to response to Cancel. This may take a few seconds."), 0)
} else {
hideDialog()
showDialog(waitForCancelDialogComponent, qsTr("Calibration Cancel"), qgcView.showDialogDefaultWidth, 0)
}
}
}
......@@ -154,6 +152,24 @@ Item {
}
}
Component {
id: waitForCancelDialogComponent
QGCViewMessage {
message: qsTr("Waiting for Vehicle to response to Cancel. This may take a few seconds.")
Connections {
target: controller
onWaitingForCancelChanged: {
if (!controller.waitingForCancel) {
hideDialog()
}
}
}
}
}
Component {
id: preCalibrationDialogComponent
......@@ -349,11 +365,12 @@ Item {
spacing: ScreenTools.defaultFontPixelHeight / 2
IndicatorButton {
property bool _hasMag: controller.parameterExists(-1, "SYS_HAS_MAG") ? controller.getParameterFact(-1, "SYS_HAS_MAG").value !== 0 : true
id: compassButton
width: _buttonWidth
text: qsTr("Compass")
indicatorGreen: cal_mag0_id.value !== 0
visible: QGroundControl.corePlugin.options.showSensorCalibrationCompass && showSensorCalibrationCompass
visible: _hasMag && QGroundControl.corePlugin.options.showSensorCalibrationCompass && showSensorCalibrationCompass
onClicked: {
preCalibrationDialogType = "compass"
......@@ -410,7 +427,7 @@ Item {
width: _buttonWidth
text: qsTr("Airspeed")
visible: (controller.vehicle.fixedWing || controller.vehicle.vtol) &&
controller.getParameterFact(-1, "FW_ARSP_MODE").value === false &&
controller.getParameterFact(-1, "FW_ARSP_MODE").value == 0 &&
controller.getParameterFact(-1, "CBRK_AIRSPD_CHK").value !== 162128 &&
QGroundControl.corePlugin.options.showSensorCalibrationAirspeed &&
showSensorCalibrationAirspeed
......
......@@ -790,7 +790,7 @@ QGCCameraControl::_loadSettings(const QDomNodeList nodeList)
QVariant typedValue;
QString errorString;
if (metaData->convertAndValidateRaw(attr, true /* convertOnly */, typedValue, errorString)) {
metaData->setIncrement(typedValue.toDouble());
metaData->setRawIncrement(typedValue.toDouble());
} else {
qWarning() << "Invalid step value for" << factName
<< " type:" << metaData->type()
......
......@@ -8,6 +8,7 @@
****************************************************************************/
#include "Fact.h"
#include "FactValueSliderListModel.h"
#include "QGCMAVLink.h"
#include "QGCApplication.h"
#include "QGCCorePlugin.h"
......@@ -18,13 +19,14 @@
static const char* kMissingMetadata = "Meta data pointer missing";
Fact::Fact(QObject* parent)
: QObject(parent)
, _componentId(-1)
, _rawValue(0)
, _type(FactMetaData::valueTypeInt32)
, _metaData(NULL)
, _sendValueChangedSignals(true)
: QObject (parent)
, _componentId (-1)
, _rawValue (0)
, _type (FactMetaData::valueTypeInt32)
, _metaData (NULL)
, _sendValueChangedSignals (true)
, _deferredValueChangeSignal(false)
, _valueSliderModel (NULL)
{
FactMetaData* metaData = new FactMetaData(_type, this);
setMetaData(metaData);
......@@ -34,14 +36,15 @@ Fact::Fact(QObject* parent)
}
Fact::Fact(int componentId, QString name, FactMetaData::ValueType_t type, QObject* parent)
: QObject(parent)
, _name(name)
, _componentId(componentId)
, _rawValue(0)
, _type(type)
, _metaData(NULL)
, _sendValueChangedSignals(true)
: QObject (parent)
, _name (name)
, _componentId (componentId)
, _rawValue (0)
, _type (type)
, _metaData (NULL)
, _sendValueChangedSignals (true)
, _deferredValueChangeSignal(false)
, _valueSliderModel (NULL)
{
FactMetaData* metaData = new FactMetaData(_type, this);
setMetaData(metaData);
......@@ -57,9 +60,8 @@ Fact::Fact(FactMetaData* metaData, QObject* parent)
, _metaData (NULL)
, _sendValueChangedSignals (true)
, _deferredValueChangeSignal(false)
, _valueSliderModel (NULL)
{
// Allow core plugin a chance to override the default value
qgcApp()->toolbox()->corePlugin()->adjustSettingMetaData(*metaData);
setMetaData(metaData, true /* setDefaultFromMetaData */);
}
......@@ -78,7 +80,7 @@ const Fact& Fact::operator=(const Fact& other)
_type = other._type;
_sendValueChangedSignals = other._sendValueChangedSignals;
_deferredValueChangeSignal = other._deferredValueChangeSignal;
_valueSliderModel = NULL;
if (_metaData && other._metaData) {
*_metaData = *other._metaData;
} else {
......@@ -633,10 +635,20 @@ QString Fact::enumOrValueString(void)
return QString();
}
double Fact::increment(void) const
double Fact::rawIncrement(void) const
{
if (_metaData) {
return _metaData->increment();
return _metaData->rawIncrement();
} else {
qWarning() << kMissingMetadata << name();
}
return std::numeric_limits<double>::quiet_NaN();
}
double Fact::cookedIncrement(void) const
{
if (_metaData) {
return _metaData->cookedIncrement();
} else {
qWarning() << kMissingMetadata << name();
}
......@@ -682,3 +694,11 @@ bool Fact::volatileValue(void) const
return false;
}
}
FactValueSliderListModel* Fact::valueSliderModel(void)
{
if (!_valueSliderModel) {
_valueSliderModel = new FactValueSliderListModel(*this);
}
return _valueSliderModel;
}
......@@ -20,6 +20,9 @@
#include <QString>
#include <QVariant>
#include <QDebug>
#include <QAbstractListModel>
class FactValueSliderListModel;
/// @brief A Fact is used to hold a single value within the system.
class Fact : public QObject
......@@ -66,7 +69,7 @@ public:
Q_PROPERTY(bool valueEqualsDefault READ valueEqualsDefault NOTIFY valueChanged)
Q_PROPERTY(QString valueString READ cookedValueString NOTIFY valueChanged)
Q_PROPERTY(QString enumOrValueString READ enumOrValueString NOTIFY valueChanged)
Q_PROPERTY(double increment READ increment CONSTANT)
Q_PROPERTY(double increment READ cookedIncrement CONSTANT)
Q_PROPERTY(bool typeIsString READ typeIsString CONSTANT)
Q_PROPERTY(bool typeIsBool READ typeIsBool CONSTANT)
Q_PROPERTY(bool hasControl READ hasControl CONSTANT)
......@@ -115,7 +118,8 @@ public:
bool valueEqualsDefault (void) const;
bool rebootRequired (void) const;
QString enumOrValueString (void); // This is not const, since an unknown value can modify the enum lists
double increment (void) const;
double rawIncrement (void) const;
double cookedIncrement (void) const;
bool typeIsString (void) const { return type() == FactMetaData::valueTypeString; }
bool typeIsBool (void) const { return type() == FactMetaData::valueTypeBool; }
bool hasControl (void) const;
......@@ -123,6 +127,8 @@ public:
bool writeOnly (void) const;
bool volatileValue (void) const;
Q_INVOKABLE FactValueSliderListModel* valueSliderModel(void);
/// Returns the values as a string with full 18 digit precision if float/double.
QString rawValueStringFullPrecision(void) const;
......@@ -192,6 +198,7 @@ protected:
FactMetaData* _metaData;
bool _sendValueChangedSignals;
bool _deferredValueChangeSignal;
FactValueSliderListModel* _valueSliderModel;
};
#endif
......@@ -8,7 +8,8 @@ import QGroundControl.Controls 1.0
QGCCheckBox {
property Fact fact: Fact { }
property variant checkedValue: 1
property variant uncheckedValue: 0
checkedState: fact ?
(fact.typeIsBool ?
(fact.value === false ? Qt.Unchecked : Qt.Checked) :
......@@ -17,5 +18,5 @@ QGCCheckBox {
text: qsTr("Label")
onClicked: fact.value = checked ? 1 : 0
onClicked: fact.value = (checked ? checkedValue : uncheckedValue)
}
......@@ -88,6 +88,8 @@ void FactPanelController::_reportMissingParameter(int componentId, const QString
QString missingParam = QString("%1:%2").arg(componentId).arg(name);
qCWarning(FactPanelControllerLog) << "Missing parameter:" << missingParam;
// If missing parameters a reported from the constructor of a derived class we
// will not have access to _factPanel yet. Just record list of missing facts
// in that case instead of notify. Once _factPanel is available they will be
......
......@@ -20,16 +20,11 @@ QGCTextField {
property string _validateString
// At this point all Facts are numeric
inputMethodHints: ((fact && fact.typeIsString) || ScreenTools.isiOS) ?
Qt.ImhNone : // iOS numeric keyboard has no done button, we can't use it
Qt.ImhFormattedNumbersOnly // Forces use of virtual numeric keyboard
onEditingFinished: {
if (ScreenTools.isMobile) {
// Toss focus on mobile after Done on virtual keyboard. Prevent strange interactions.
focus = false
}
if (typeof qgcView !== 'undefined' && qgcView) {
var errorString = fact.validate(text, false /* convertOnly */)
if (errorString === "") {
......
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.2
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FactSystem 1.0
Rectangle {
height: _itemHeight
width: _totalSlots * _itemWidth
color: qgcPal.textField
property Fact fact: undefined
property int digitCount: 4 ///< The number of digits to show for each value
property int incrementSlots: 1 ///< The number of visible slots to left/right of center value
property int _totalDigitCount: digitCount + 1 + fact.units.length
property real _margins: (ScreenTools.implicitTextFieldHeight - ScreenTools.defaultFontPixelHeight) / 2
property real _increment: fact.increment
property real _value: fact.value
property int _decimalPlaces: fact.decimalPlaces
property string _units: fact.units
property real _prevValue: _value - _increment
property real _nextValue: _value + _increment
property real _itemWidth: (_totalDigitCount * ScreenTools.defaultFontPixelWidth) + (_margins * 2)
property real _itemHeight: ScreenTools.implicitTextFieldHeight
property var _valueModel
property int _totalSlots: (incrementSlots * 2) + 1
property int _currentIndex: _totalSlots / 2
property int _currentRelativeIndex: _currentIndex
property int _prevIncrementSlots: incrementSlots
property int _nextIncrementSlots: incrementSlots
property int _selectionWidth: 3
property var _model: fact.valueSliderModel()
property var _fact: fact
QGCPalette { id: qgcPal; colorGroupEnabled: parent.enabled }
QGCPalette { id: qgcPalDisabled; colorGroupEnabled: false }
function firstVisibleIndex() {
return valueListView.contentX / _itemWidth
}
function recalcRelativeIndex() {
_currentRelativeIndex = _currentIndex - firstVisibleIndex()
_prevIncrementSlots = _currentRelativeIndex
_nextIncrementSlots = _totalSlots - _currentRelativeIndex - 1
}
function reset() {
valueListView.positionViewAtIndex(0, ListView.Beginning)
_currentIndex = _model.resetInitialValue()
valueListView.positionViewAtIndex(_currentIndex, ListView.Center)
recalcRelativeIndex()
}
Component.onCompleted: {
valueListView.maximumFlickVelocity = valueListView.maximumFlickVelocity / 2
reset()
}
Connections {
target: _fact
onValueChanged: reset()
}
Component {
id: editDialogComponent
ParameterEditorDialog {
fact: _fact
}
}
QGCListView {
id: valueListView
anchors.fill: parent
orientation: ListView.Horizontal
snapMode: ListView.SnapToItem
clip: true
model: _model
delegate: QGCLabel {
width: _itemWidth
height: _itemHeight
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: value + " " + _units
color: qgcPal.textFieldText
MouseArea {
anchors.fill: parent
onClicked: {
valueListView.focus = true
if (_currentIndex === index) {
qgcView.showDialog(editDialogComponent, qsTr("Value Details"), qgcView.showDialogDefaultWidth, StandardButton.Save | StandardButton.Cancel)
} else {
_currentIndex = index
valueListView.positionViewAtIndex(_currentIndex, ListView.Center)
recalcRelativeIndex()
fact.value = value
}
}
}
}
onMovementStarted: valueListView.focus = true
onMovementEnded: {
_currentIndex = firstVisibleIndex() + _currentRelativeIndex
fact.value = _model.valueAtModelIndex(_currentIndex)
}
}
Rectangle {
id: leftOverlay
width: _itemWidth * _prevIncrementSlots
height: _itemHeight
color: qgcPal.textField
opacity: 0.5
}
Rectangle {
width: _itemWidth * _nextIncrementSlots
height: _itemHeight
anchors.right: parent.right
color: qgcPal.textField
opacity: 0.5
}
Rectangle {
x: _currentRelativeIndex * _itemWidth - _borderWidth
y: -_borderWidth
width: _itemWidth + (_borderWidth * 2)
height: _itemHeight + (_borderWidth * 2)
border.width: _borderWidth
border.color: qgcPal.brandingBlue
color: "transparent"
readonly property int _borderWidth: 3
}
}
......@@ -8,3 +8,4 @@ FactPanel 1.0 FactPanel.qml
FactTextField 1.0 FactTextField.qml
FactTextFieldGrid 1.0 FactTextFieldGrid.qml
FactTextFieldRow 1.0 FactTextFieldRow.qml
FactValueSlider 1.0 FactValueSlider.qml
......@@ -105,6 +105,7 @@ void FactGroup::_addFact(Fact* fact, const QString& name)
fact->setMetaData(_nameToFactMetaDataMap[name]);
}
_nameToFactMap[name] = fact;
_factNames.append(name);
}
void FactGroup::_addFactGroup(FactGroup* factGroup, const QString& name)
......
......@@ -38,7 +38,7 @@ public:
/// @return FactGroup for specified name, NULL if not found
Q_INVOKABLE FactGroup* getFactGroup(const QString& name);
QStringList factNames(void) const { return _nameToFactMap.keys(); }
QStringList factNames(void) const { return _factNames; }
QStringList factGroupNames(void) const { return _nameToFactGroupMap.keys(); }
protected:
......@@ -59,7 +59,7 @@ protected:
QMap<QString, Fact*> _nameToFactMap;
QMap<QString, FactGroup*> _nameToFactGroupMap;
QMap<QString, FactMetaData*> _nameToFactMetaDataMap;
QStringList _factNames;
};
#endif
This diff is collapsed.
......@@ -111,7 +111,8 @@ public:
/// Amount to increment value when used in controls such as spin button or slider with detents.
/// NaN for no increment available.
double increment (void) const { return _increment; }
double rawIncrement (void) const { return _rawIncrement; }
double cookedIncrement (void) const;
Translator rawTranslator (void) const { return _rawTranslator; }
Translator cookedTranslator (void) const { return _cookedTranslator; }
......@@ -135,7 +136,7 @@ public:
void setShortDescription(const QString& shortDescription) { _shortDescription = shortDescription; }
void setRawUnits (const QString& rawUnits);
void setRebootRequired (bool rebootRequired) { _rebootRequired = rebootRequired; }
void setIncrement (double increment) { _increment = increment; }
void setRawIncrement (double increment) { _rawIncrement = increment; }
void setHasControl (bool bValue) { _hasControl = bValue; }
void setReadOnly (bool bValue) { _readOnly = bValue; }
void setWriteOnly (bool bValue) { _writeOnly = bValue; }
......@@ -215,7 +216,7 @@ private:
};
struct AppSettingsTranslation_s {
const char* rawUnits;
QString rawUnits;
const char* cookedUnits;
UnitTypes unitType;
uint32_t unitOption;
......@@ -248,7 +249,7 @@ private:
Translator _rawTranslator;
Translator _cookedTranslator;
bool _rebootRequired;
double _increment;
double _rawIncrement;
bool _hasControl;
bool _readOnly;
bool _writeOnly;
......@@ -264,7 +265,7 @@ private:
} constants;
struct BuiltInTranslation_s {
const char* rawUnits;
QString rawUnits;
const char* cookedUnits;
Translator rawTranslator;
Translator cookedTranslator;
......@@ -285,6 +286,7 @@ private:
static const char* _mobileDefaultValueJsonKey;
static const char* _minJsonKey;
static const char* _maxJsonKey;
static const char* _incrementJsonKey;
static const char* _hasControlJsonKey;
};
......
......@@ -20,10 +20,6 @@
/// The components of the FactSystem are a Fact which holds an individual value. FactMetaData holds
/// additional meta data associated with a Fact such as description, min/max ranges and so forth.
/// The FactValidator object is a QML validator which validates input according to the FactMetaData
/// settings. Client code can then use this system to expose sets of Facts to QML code. An example
/// of this is the PX4ParameterMetaData onbject which is part of the PX4 AutoPilot plugin. It exposes
/// the firmware parameters to QML such that you can bind QML ui elements directly to parameters.
class FactSystem : public QGCTool
{
......
/****************************************************************************
*
* (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.
*
****************************************************************************/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef FactValidator_H
#define FactValidator_H
#include <QValidator>
class Fact;
/// QML Validator for Facts (Work In Progress)
///
/// The validator uses the FactMetaData to impose restrictions on the input. It is used as follows:
/// @code{.unparsed}
/// TextInput {
/// validator: FactValidator { fact: parameters["RC_MAP_THROTTLE"]; }
/// }
/// @endcode
class FactValidator : public QValidator
{
Q_OBJECT
Q_PROPERTY(Fact* fact READ fact WRITE setFact)
public:
FactValidator(QObject* parent = NULL);
// Property system methods
/// Read accessor for fact property
Fact* fact(void) { return _fact; }
/// Write accessor for fact property
void setFact(Fact* fact) { _fact = fact; }
/// Override from QValidator
virtual void fixup(QString& input) const;
/// Override from QValidator
virtual State validate(QString& input, int& pos) const;
private:
Fact* _fact; ///< Fact that the validator is working on
};
#endif
\ 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 "FactValueSliderListModel.h"
#include <QDebug>
#include <QQmlEngine>
#include <QtMath>
#include <math.h>
const int FactValueSliderListModel::_valueRole = Qt::UserRole;
const int FactValueSliderListModel::_valueIndexRole = Qt::UserRole + 1;
FactValueSliderListModel::FactValueSliderListModel(Fact& fact, QObject* parent)
: QAbstractListModel (parent)
, _fact (fact)
, _cValues (0)
, _firstValueIndexInWindow (0)
, _initialValueIndex (0)
, _cPrevValues (0)
, _cNextValues (0)
, _initialValue (0)
, _initialValueRounded (0)
, _increment (0)
{
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
}
FactValueSliderListModel::~FactValueSliderListModel()
{
}
int FactValueSliderListModel::resetInitialValue(void)
{
if (_cValues > 0) {
// Remove any old rows
beginRemoveRows(QModelIndex(), 0, _cValues - 1);
_cValues = 0;
endRemoveRows();
}
_initialValue = _fact.cookedValue().toDouble();
_initialValueRounded = qRound(_initialValue);
if (qRound(_fact.rawIncrement()) == _fact.rawIncrement()) {
_increment = qRound(_fact.cookedIncrement());
} else {
_increment = _fact.cookedIncrement();
}
_cPrevValues = qMin((_initialValue - _fact.cookedMin().toDouble()), 1000.0) / _increment;
_cNextValues = qMin((_fact.cookedMax().toDouble() - _initialValue), 1000.0) / _increment;
_initialValueIndex = _cPrevValues;
int totalValueCount = _cPrevValues + 1 + _cNextValues;
beginInsertRows(QModelIndex(), 0, totalValueCount - 1);
_cValues = totalValueCount;
endInsertRows();
return _initialValueIndex;
}
int FactValueSliderListModel::rowCount(const QModelIndex& parent) const
{
Q_UNUSED(parent);
return _cValues;
}
QVariant FactValueSliderListModel::data(const QModelIndex &index, int role) const
{
Q_UNUSED(role);
if (!index.isValid()) {
return QVariant();
}
int valueIndex = index.row();
if (valueIndex >= _cValues) {
return QVariant();
}
if (role == _valueRole) {
double value;
int cIncrementCount = valueIndex - _initialValueIndex;
if (cIncrementCount == 0) {
value = _initialValue;
} else {
value = _initialValueRounded + (cIncrementCount * _increment);
}
double precision = qPow(10, _fact.decimalPlaces());
double atPrecision = qRound(value * precision) / precision;
//qDebug() << value << precision << atPrecision << _fact.decimalPlaces() << _fact.name();
return QVariant(atPrecision);
} else if (role == _valueIndexRole) {
return QVariant::fromValue(valueIndex);
} else {
return QVariant();
}
}
QHash<int, QByteArray> FactValueSliderListModel::roleNames(void) const
{
QHash<int, QByteArray> hash;
hash[_valueRole] = "value";
hash[_valueIndexRole] = "valueIndex";
return hash;
}
double FactValueSliderListModel::valueAtModelIndex(int index)
{
return data(createIndex(index, 0), _valueRole).toDouble();
}
int FactValueSliderListModel::valueIndexAtModelIndex(int index)
{
return data(createIndex(index, 0), _valueIndexRole).toInt();
}
/****************************************************************************
*
* (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 <QAbstractListModel>
#include "Fact.h"
/// Provides a list model of values for incrementing/decrementing the value of a Fact
class FactValueSliderListModel : public QAbstractListModel
{
Q_OBJECT
public:
FactValueSliderListModel(Fact& fact, QObject* parent = NULL);
~FactValueSliderListModel();
Q_INVOKABLE int resetInitialValue(void);
Q_INVOKABLE double valueAtModelIndex(int index);
Q_INVOKABLE int valueIndexAtModelIndex(int index);
private:
// Overrides from QAbstractListModel
int rowCount(const QModelIndex & parent = QModelIndex()) const override;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames(void) const override;
Fact& _fact;
int _cValues;
int _firstValueIndexInWindow;
int _initialValueIndex;
int _cPrevValues;
int _cNextValues;
int _windowSize;
double _initialValue;
double _initialValueRounded;
double _increment;
static const int _valueRole;
static const int _valueIndexRole;
};
......@@ -86,7 +86,7 @@ ParameterManager::ParameterManager(Vehicle* vehicle)
_waitingForDefaultComponent = false;
emit parametersReadyChanged(_parametersReady);
emit missingParametersChanged(_missingParameters);
} else {
} else if (!_logReplay){
refreshAllParameters();
}
}
......@@ -358,7 +358,7 @@ void ParameterManager::_parameterUpdate(int vehicleId, int componentId, QString
// Update param cache. The param cache is only used on PX4 Firmware since ArduPilot and Solo have volatile params
// which invalidate the cache. The Solo also streams param updates in flight for things like gimbal values
// which in turn causes a perf problem with all the param cache updates.
if (_vehicle->px4Firmware()) {
if (!_logReplay && _vehicle->px4Firmware()) {
if (_prevWaitingReadParamIndexCount + _prevWaitingReadParamNameCount != 0 && readWaitingParamCount == 0) {
// All reads just finished, update the cache
_writeLocalParamCache(vehicleId, componentId);
......@@ -604,6 +604,10 @@ bool ParameterManager::_fillIndexBatchQueue(bool waitingParamTimeout)
void ParameterManager::_waitingParamTimeout(void)
{
if (_logReplay) {
return;
}
bool paramsRequested = false;
const int maxBatchSize = 10;
int batchCount = 0;
......
......@@ -7,9 +7,7 @@
*
****************************************************************************/
#ifndef ParameterManager_H
#define ParameterManager_H
#pragma once
#include <QObject>
#include <QMap>
......@@ -25,33 +23,26 @@
#include "QGCMAVLink.h"
#include "Vehicle.h"
/// @file
/// @author Don Gagne <don@thegagnes.com>
Q_DECLARE_LOGGING_CATEGORY(ParameterManagerVerbose1Log)
Q_DECLARE_LOGGING_CATEGORY(ParameterManagerVerbose2Log)
Q_DECLARE_LOGGING_CATEGORY(ParameterManagerDebugCacheFailureLog)
/// Connects to Parameter Manager to load/update Facts
class ParameterManager : public QObject
{
Q_OBJECT
public:
/// @param uas Uas which this set of facts is associated with
ParameterManager(Vehicle* vehicle);
~ParameterManager();
/// true: Parameters are ready for use
Q_PROPERTY(bool parametersReady READ parametersReady NOTIFY parametersReadyChanged)
bool parametersReady(void) { return _parametersReady; }
ParameterManager (Vehicle* vehicle);
~ParameterManager ();
/// true: Parameters are missing from firmware response, false: all parameters received from firmware
Q_PROPERTY(bool missingParameters READ missingParameters NOTIFY missingParametersChanged)
bool missingParameters(void) { return _missingParameters; }
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(double loadProgress READ loadProgress NOTIFY loadProgressChanged)
double loadProgress(void) const { return _loadProgress; }
bool parametersReady (void) const { return _parametersReady; }
bool missingParameters (void) const { return _missingParameters; }
double loadProgress (void) const { return _loadProgress; }
/// @return Directory of parameter caches
static QDir parameterCacheDir();
......@@ -59,7 +50,6 @@ public:
/// @return Location of parameter cache file
static QString parameterCacheFile(int vehicleId, int componentId);
/// Re-request the full set of parameters from the autopilot
void refreshAllParameters(uint8_t componentID = MAV_COMP_ID_ALL);
......@@ -217,5 +207,3 @@ private:
static const char* _jsonParamNameKey;
static const char* _jsonParamValueKey;
};
#endif
......@@ -20,19 +20,19 @@ SettingsFact::SettingsFact(QObject* parent)
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
}
SettingsFact::SettingsFact(QString settingGroup, FactMetaData* metaData, QObject* parent)
: Fact(0, metaData->name(), metaData->type(), parent)
, _settingGroup(settingGroup)
, _visible(true)
SettingsFact::SettingsFact(QString settingsGroup, FactMetaData* metaData, QObject* parent)
: Fact (0, metaData->name(), metaData->type(), parent)
, _settingsGroup(settingsGroup)
, _visible (true)
{
QSettings settings;
if (!_settingGroup.isEmpty()) {
settings.beginGroup(_settingGroup);
if (!_settingsGroup.isEmpty()) {
settings.beginGroup(_settingsGroup);
}
// Allow core plugin a chance to override the default value
_visible = qgcApp()->toolbox()->corePlugin()->adjustSettingMetaData(*metaData);
_visible = qgcApp()->toolbox()->corePlugin()->adjustSettingMetaData(settingsGroup, *metaData);
setMetaData(metaData);
QVariant rawDefaultValue = metaData->rawDefaultValue();
......@@ -60,7 +60,7 @@ const SettingsFact& SettingsFact::operator=(const SettingsFact& other)
{
Fact::operator=(other);
_settingGroup = other._settingGroup;
_settingsGroup = other._settingsGroup;
return *this;
}
......@@ -69,8 +69,8 @@ void SettingsFact::_rawValueChanged(QVariant value)
{
QSettings settings;
if (!_settingGroup.isEmpty()) {
settings.beginGroup(_settingGroup);
if (!_settingsGroup.isEmpty()) {
settings.beginGroup(_settingsGroup);
}
settings.setValue(_name, value);
......
......@@ -7,12 +7,7 @@
*
****************************************************************************/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef SettingsFact_H
#define SettingsFact_H
#pragma once
#include "Fact.h"
......@@ -23,7 +18,7 @@ class SettingsFact : public Fact
public:
SettingsFact(QObject* parent = NULL);
SettingsFact(QString settingGroup, FactMetaData* metaData, QObject* parent = NULL);
SettingsFact(QString settingsGroup, FactMetaData* metaData, QObject* parent = NULL);
SettingsFact(const SettingsFact& other, QObject* parent = NULL);
const SettingsFact& operator=(const SettingsFact& other);
......@@ -37,8 +32,6 @@ private slots:
void _rawValueChanged(QVariant value);
private:
QString _settingGroup;
QString _settingsGroup;
bool _visible;
};
#endif
......@@ -366,6 +366,8 @@ bool APMFirmwarePlugin::_handleIncomingStatusText(Vehicle* vehicle, mavlink_mess
supportedMinorNumber = 4;
break;
case MAV_TYPE_QUADROTOR:
// Start TCP video handshake with ARTOO in case it's a Solo running ArduPilot firmware
_soloVideoHandshake(vehicle, false /* originalSoloFirmware */);
case MAV_TYPE_COAXIAL:
case MAV_TYPE_HELICOPTER:
case MAV_TYPE_SUBMARINE:
......@@ -420,7 +422,7 @@ bool APMFirmwarePlugin::_handleIncomingStatusText(Vehicle* vehicle, mavlink_mess
_setInfoSeverity(message);
// Start TCP video handshake with ARTOO
_soloVideoHandshake(vehicle);
_soloVideoHandshake(vehicle, true /* originalSoloFirmware */);
} else if (messageText.contains(APM_FRAME_REXP)) {
// We need to parse the Frame: message in order to determine whether the motors are coaxial or not
QRegExp frameTypeRegex("^Frame: (\\S*)");
......@@ -595,6 +597,18 @@ void APMFirmwarePlugin::_adjustCalibrationMessageSeverity(mavlink_message_t* mes
mavlink_msg_statustext_encode_chan(message->sysid, message->compid, 0, message, &statusText);
}
void APMFirmwarePlugin::initializeStreamRates(Vehicle* vehicle)
{
vehicle->requestDataStream(MAV_DATA_STREAM_RAW_SENSORS, 2);
vehicle->requestDataStream(MAV_DATA_STREAM_EXTENDED_STATUS, 2);
vehicle->requestDataStream(MAV_DATA_STREAM_RC_CHANNELS, 2);
vehicle->requestDataStream(MAV_DATA_STREAM_POSITION, 3);
vehicle->requestDataStream(MAV_DATA_STREAM_EXTRA1, 10);
vehicle->requestDataStream(MAV_DATA_STREAM_EXTRA2, 10);
vehicle->requestDataStream(MAV_DATA_STREAM_EXTRA3, 3);
}
void APMFirmwarePlugin::initializeVehicle(Vehicle* vehicle)
{
vehicle->setFirmwarePluginInstanceData(new APMFirmwarePluginInstanceData);
......@@ -632,13 +646,7 @@ void APMFirmwarePlugin::initializeVehicle(Vehicle* vehicle)
}
} else {
// Streams are not started automatically on APM stack
vehicle->requestDataStream(MAV_DATA_STREAM_RAW_SENSORS, 2);
vehicle->requestDataStream(MAV_DATA_STREAM_EXTENDED_STATUS, 2);
vehicle->requestDataStream(MAV_DATA_STREAM_RC_CHANNELS, 2);
vehicle->requestDataStream(MAV_DATA_STREAM_POSITION, 3);
vehicle->requestDataStream(MAV_DATA_STREAM_EXTRA1, 10);
vehicle->requestDataStream(MAV_DATA_STREAM_EXTRA2, 10);
vehicle->requestDataStream(MAV_DATA_STREAM_EXTRA3, 3);
initializeStreamRates(vehicle);
}
}
......@@ -744,14 +752,16 @@ bool APMFirmwarePlugin::isGuidedMode(const Vehicle* vehicle) const
return vehicle->flightMode() == "Guided";
}
void APMFirmwarePlugin::_soloVideoHandshake(Vehicle* vehicle)
void APMFirmwarePlugin::_soloVideoHandshake(Vehicle* vehicle, bool originalSoloFirmware)
{
Q_UNUSED(vehicle);
QTcpSocket* socket = new QTcpSocket();
socket->connectToHost(_artooIP, _artooVideoHandshakePort);
QObject::connect(socket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error), this, &APMFirmwarePlugin::_artooSocketError);
if (originalSoloFirmware) {
QObject::connect(socket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error), this, &APMFirmwarePlugin::_artooSocketError);
}
}
void APMFirmwarePlugin::_artooSocketError(QAbstractSocket::SocketError socketError)
......@@ -781,6 +791,8 @@ QString APMFirmwarePlugin::internalParameterMetaDataFile(Vehicle* vehicle)
return QStringLiteral(":/FirmwarePlugin/APM/APMParameterFactMetaData.Copter.3.4.xml");
case 5:
return QStringLiteral(":/FirmwarePlugin/APM/APMParameterFactMetaData.Copter.3.5.xml");
case 6:
return QStringLiteral(":/FirmwarePlugin/APM/APMParameterFactMetaData.Copter.3.6.xml");
default:
if (minorVersion < 3) {
return QStringLiteral(":/FirmwarePlugin/APM/APMParameterFactMetaData.Copter.3.3.xml");
......@@ -951,7 +963,6 @@ bool APMFirmwarePlugin::_guidedModeTakeoff(Vehicle* vehicle, double altitudeRel)
return false;
}
// FIXME: Is this needed?
if (!_armVehicleAndValidate(vehicle)) {
qgcApp()->showMessage(tr("Unable to takeoff: Vehicle failed to arm."));
return false;
......@@ -966,36 +977,35 @@ bool APMFirmwarePlugin::_guidedModeTakeoff(Vehicle* vehicle, double altitudeRel)
return true;
}
// FIXME: Review for a better way to do this
void APMFirmwarePlugin::startMission(Vehicle* vehicle)
{
double currentAlt = vehicle->altitudeRelative()->rawValue().toDouble();
if (!vehicle->flying()) {
if (_guidedModeTakeoff(vehicle, qQNaN())) {
if (vehicle->flying()) {
// Vehicle already in the air, we just need to switch to auto
if (!_setFlightModeAndValidate(vehicle, "Auto")) {
qgcApp()->showMessage(tr("Unable to start mission: Vehicle failed to change to Auto mode."));
}
return;
}
// Wait for vehicle to get off ground before switching to auto (10 seconds)
bool didTakeoff = false;
for (int i=0; i<100; i++) {
if (vehicle->altitudeRelative()->rawValue().toDouble() >= currentAlt + 1.0) {
didTakeoff = true;
break;
}
QGC::SLEEP::msleep(100);
qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents);
}
if (!vehicle->armed()) {
// First switch to flight mode we can arm from
if (!_setFlightModeAndValidate(vehicle, "Guided")) {
qgcApp()->showMessage(tr("Unable to start mission: Vehicle failed to change to Guided mode."));
return;
}
if (!didTakeoff) {
qgcApp()->showMessage(tr("Unable to start mission. Vehicle takeoff failed."));
return;
}
} else {
if (!_armVehicleAndValidate(vehicle)) {
qgcApp()->showMessage(tr("Unable to start mission: Vehicle failed to arm."));
return;
}
}
if (!_setFlightModeAndValidate(vehicle, missionFlightMode())) {
qgcApp()->showMessage(tr("Unable to start mission. Vehicle failed to change to auto."));
return;
if (vehicle->fixedWing()) {
if (!_setFlightModeAndValidate(vehicle, "Auto")) {
qgcApp()->showMessage(tr("Unable to start mission: Vehicle failed to change to Auto mode."));
return;
}
} else {
vehicle->sendMavCommand(vehicle->defaultComponentId(), MAV_CMD_MISSION_START, true /*show error */);
}
}
......@@ -92,6 +92,7 @@ public:
int manualControlReservedButtonCount(void) override;
bool adjustIncomingMavlinkMessage (Vehicle* vehicle, mavlink_message_t* message) override;
void adjustOutgoingMavlinkMessage (Vehicle* vehicle, LinkInterface* outgoingLink, mavlink_message_t* message) override;
virtual void initializeStreamRates (Vehicle* vehicle);
void initializeVehicle (Vehicle* vehicle) override;
bool sendHomePositionToVehicle (void) override;
void addMetaDataToFact (QObject* parameterMetaData, Fact* fact, MAV_TYPE vehicleType) override;
......@@ -102,6 +103,7 @@ public:
QObject* loadParameterMetaData (const QString& metaDataFile) override;
QString brandImageIndoor (const Vehicle* vehicle) const override { Q_UNUSED(vehicle); return QStringLiteral("/qmlimages/APM/BrandImage"); }
QString brandImageOutdoor (const Vehicle* vehicle) const override { Q_UNUSED(vehicle); return QStringLiteral("/qmlimages/APM/BrandImage"); }
bool supportsTerrainFrame (void) const override { return true; }
protected:
/// All access to singleton is through stack specific implementation
......@@ -123,7 +125,7 @@ private:
bool _handleIncomingStatusText(Vehicle* vehicle, mavlink_message_t* message);
void _handleIncomingHeartbeat(Vehicle* vehicle, mavlink_message_t* message);
void _handleOutgoingParamSet(Vehicle* vehicle, LinkInterface* outgoingLink, mavlink_message_t* message);
void _soloVideoHandshake(Vehicle* vehicle);
void _soloVideoHandshake(Vehicle* vehicle, bool originalSoloFirmware);
bool _guidedModeTakeoff(Vehicle* vehicle, double altitudeRel);
// Any instance data here must be global to all vehicles
......
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.
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.
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.
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.
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.
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.
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