Commit d18a6b85 authored by dogmaphobic's avatar dogmaphobic

Merge remote-tracking branch 'MavLink/master' into logHandling

* MavLink/master:
  Warn on unsupported APM version
  APM stack does not support RC cal start/stop
  Harden code for missing params, handle APM special case
  Fix default comp id detection
  PX4 Firmware no longer requires mavlink USB start
  Standard sizing for QGCView::showDialog
  Standard sizing for QGCView::showDialog
  UAS Object: Avoid spamming the console on successful commands
  linux include required libraries
  Show enumStringValue if available
  Use combo box if enums available
  Set proper default mode for VTOL
  Teach mission manager about transition command
  Support camera and VTOL transition commands
  Better light disabled text color
  Add better button highlight color for light theme
  Change selected flight mode color
  Update README.md
  Simplifying Airframe config
  Fixing crash bug.

Conflicts:
	src/ui/MainWindow.cc
parents 939ee6f4 d8c45c77
......@@ -99,6 +99,47 @@ WindowsBuild {
}
LinuxBuild {
QMAKE_POST_LINK += && mkdir -p $$DESTDIR/libs
# QT_INSTALL_LIBS
QT_LIB_LIST = \
libicudata.so.54 \
libicui18n.so.54 \
libicuuc.so.54 \
libQt5Core.so.5 \
libQt5DBus.so.5 \
libQt5Gui.so.5 \
libQt5Location.so.5 \
libQt5Network.so.5 \
libQt5OpenGL.so.5 \
libQt5Positioning.so.5 \
libQt5PrintSupport.so.5 \
libQt5Qml.so.5 \
libQt5Quick.so.5 \
libQt5QuickWidgets.so.5 \
libQt5SerialPort.so.5 \
libQt5Svg.so.5 \
libQt5Test.so.5 \
libQt5Widgets.so.5 \
libQt5XcbQpa.so.5
for(QT_LIB, QT_LIB_LIST) {
QMAKE_POST_LINK += && $$QMAKE_COPY --dereference $$[QT_INSTALL_LIBS]/$$QT_LIB $$DESTDIR/libs
}
# QT_INSTALL_PLUGINS
QT_PLUGIN_LIST = \
platforms \
xcbglintegrations
for(QT_PLUGIN, QT_PLUGIN_LIST) {
QMAKE_POST_LINK += && $$QMAKE_COPY --dereference --recursive $$[QT_INSTALL_PLUGINS]/$$QT_PLUGIN $$DESTDIR/libs
}
# QT_INSTALL_QML
QMAKE_POST_LINK += && $$QMAKE_COPY --dereference --recursive $$[QT_INSTALL_QML] $$DESTDIR/libs
# QGroundControl start script
QMAKE_POST_LINK += && $$QMAKE_COPY $$BASEDIR/deploy/qgroundcontrol-start.sh $$DESTDIR
}
......@@ -22,7 +22,7 @@ Source code for QGroundControl is kept on GitHub: https://github.com/mavlink/qgr
```
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.
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.
### Supported Builds
QGroundControl builds are supported for OSX, Linux, Windows and Android. QGroundControl uses [Qt](http://www.qt.io) as it's cross-platform support library and uses [QtCreator](http://doc.qt.io/qtcreator/index.html) as it's default build environment.
......
#!/bin/sh
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/Qt/5.5/gcc_64/lib
export QML_IMPORT_PATH=$HOME/Qt/5.5/gcc_64/qml/
export QML2_IMPORT_PATH=$HOME/Qt/5.5/gcc_64/qml/
export QT_QPA_PLATFORM_PLUGIN_PATH=$HOME/Qt/5.5/gcc_64/plugins/platforms/
export LD_LIBRARY_PATH=`pwd`/libs:$LD_LIBRARY_PATH
export QML_IMPORT_PATH=`pwd`/libs/qml
export QML2_IMPORT_PATH=`pwd`/libs/qml
export QT_QPA_PLATFORM_PLUGIN_PATH=`pwd`/libs/platforms
./qgroundcontrol "$@"
<?xml version='1.0' encoding='UTF-8'?>
<airframes>
<version>1</version>
<airframe_group image="AirframeQuadRotorPlus.png" name="Plus Frame" id="0">
<airframe_group image="AirframeQuadRotorPlus.png" name="Plus Style: Quad, Hexa, Octo, Heli" id="0">
<airframe name="3DR Aero M" file="3DR_AERO_M.param"/>
<airframe name="3DR Aero RTF" file="3DR_Aero_RTF.param"/>
<airframe name="3DR Rover" file="3DR_Rover.param"/>
......@@ -9,26 +9,26 @@
<airframe name="Parrot Bebop" file="Parrot_Bebop.param"/>
<airframe name="Storm32" file="SToRM32-MAVLink.param"/>
</airframe_group>
<airframe_group image="AirframeQuadRotorX.png" name="X Frame, Y6A Frame" id="1">
<airframe_group image="AirframeQuadRotorX.png" name="X Style, Y6A Style: Quad, Hexa, Octo, X8, Tri, Y6A" id="1">
<airframe name="3DR X8-M RTF" file="3DR_X8-M_RTF.param"/>
<airframe name="3DR Y6A" file="3DR_Y6A_RTF.param"/>
<airframe name="3DR X8+ RTF" file="3DR_X8+_RTF.param"/>
<airframe name="3DR QUAD X4 RTF" file="3DR_QUAD_X4_RTF.param"/>
<airframe name="3DR X8" file="3DR_X8_RTF.param"/>
</airframe_group>
<airframe_group image="AirframeQuadRotorH.png" name="V Frame (3DR Iris)" id="2">
<airframe_group image="AirframeQuadRotorH.png" name="V (3DR Iris)" id="2">
<airframe name="Iris with GoPro" file="Iris with Front Mount Go Pro.param"/>
<airframe name="Iris with Tarot" file="Iris with Tarot Gimbal.param"/>
<airframe name="3DR Iris+" file="3DR_Iris+.param"/>
<airframe name="Iris" file="Iris.param"/>
</airframe_group>
<airframe_group image="AirframeQuadRotorH.png" name="V Tail Frame" id="4">
<airframe_group image="AirframeQuadRotorH.png" name="V Tail" id="4">
</airframe_group>
<airframe_group image="AirframeQuadRotorH.png" name="A Tail Frame" id="5">
<airframe_group image="AirframeQuadRotorH.png" name="A Tail" id="5">
</airframe_group>
<airframe_group name="H Frame" id="3">
<airframe_group name="H: X and H differ in prop rotation" id="3">
</airframe_group>
<airframe_group name="Y6B Frame (3DR TriCopter)" id="10">
<airframe_group name="Y6B Frame (3DR TriCopter): Y6B and Y6A differ in prop rotation" id="10">
<airframe name="3DR Y6B" file="3DR_Y6B_RTF.param"/>
</airframe_group>
<airframes>
......@@ -91,7 +91,7 @@ QGCView {
QGCLabel {
anchors.baseline: modeCombo.baseline
text: "Flight Mode " + index + ":"
color: controller.activeFlightMode == index ? qgcPal.buttonHighlight : qgcPal.text
color: controller.activeFlightMode == index ? "yellow" : qgcPal.text
}
FactComboBox {
......@@ -149,7 +149,7 @@ QGCView {
QGCLabel {
anchors.baseline: optCombo.baseline
text: "Channel option " + index + ":"
color: controller.channelOptionEnabled[modelData] ? qgcPal.buttonHighlight : qgcPal.text
color: controller.channelOptionEnabled[modelData] ? "yellow" : qgcPal.text
}
FactComboBox {
......
......@@ -34,7 +34,7 @@ import QGroundControl.ScreenTools 1.0
import QGroundControl.Controllers 1.0
QGCView {
id: rootQGCView
id: qgcView
viewPanel: panel
// Help text which is shown both in the status text area prior to pressing a cal button and in the
......@@ -157,7 +157,7 @@ QGCView {
_postCalibrationDialogParams.push("COMPASS_OFS3_Z")
}
}
showDialog(postCalibrationDialogComponent, "Calibration complete", 50, StandardButton.Ok)
showDialog(postCalibrationDialogComponent, "Calibration complete", qgcView.showDialogDefaultWidth, StandardButton.Ok)
}
}
......@@ -362,7 +362,7 @@ QGCView {
} else {
preCalibrationDialogType = "compass"
preCalibrationDialogHelp = compassHelp
showDialog(preCalibrationDialogComponent, "Calibrate Compass", 50, StandardButton.Cancel | StandardButton.Ok)
showDialog(preCalibrationDialogComponent, "Calibrate Compass", qgcView.showDialogDefaultWidth, StandardButton.Cancel | StandardButton.Ok)
}
}
}
......@@ -376,7 +376,7 @@ QGCView {
onClicked: {
preCalibrationDialogType = "accel"
preCalibrationDialogHelp = accelHelp
showDialog(preCalibrationDialogComponent, "Calibrate Accelerometer", 50, StandardButton.Cancel | StandardButton.Ok)
showDialog(preCalibrationDialogComponent, "Calibrate Accelerometer", qgcView.showDialogDefaultWidth, StandardButton.Cancel | StandardButton.Ok)
}
}
QGCButton {
......
......@@ -34,7 +34,7 @@ import QGroundControl.ScreenTools 1.0
import QGroundControl.Controllers 1.0
QGCView {
id: rootQGCView
id: qgcView
viewPanel: panel
QGCPalette { id: qgcPal; colorGroupEnabled: panel.enabled }
......@@ -51,7 +51,7 @@ QGCView {
FIXME: Turned off for now, since it prevents binding. Need to restructure to
allow binding and still check channel count
if (controller.channelCount < controller.minChannelCount) {
showDialog(channelCountDialogComponent, dialogTitle, 50, 0)
showDialog(channelCountDialogComponent, dialogTitle, qgcView.showDialogDefaultWidth, 0)
} else {
hideDialog()
}
......@@ -68,7 +68,7 @@ QGCView {
Component.onCompleted: {
controllerCompleted = true
if (rootQGCView.completedSignalled) {
if (qgcView.completedSignalled) {
controllerAndViewReady = true
controller.start()
updateChannelCount()
......@@ -283,11 +283,11 @@ QGCView {
id: rollLoader
anchors.left: rollLabel.right
anchors.right: parent.right
height: rootQGCView.defaultTextHeight
height: qgcView.defaultTextHeight
width: 100
sourceComponent: channelMonitorDisplayComponent
property real defaultTextWidth: rootQGCView.defaultTextWidth
property real defaultTextWidth: qgcView.defaultTextWidth
property bool mapped: controller.rollChannelMapped
property bool reversed: controller.rollChannelReversed
}
......@@ -313,11 +313,11 @@ QGCView {
id: pitchLoader
anchors.left: pitchLabel.right
anchors.right: parent.right
height: rootQGCView.defaultTextHeight
height: qgcView.defaultTextHeight
width: 100
sourceComponent: channelMonitorDisplayComponent
property real defaultTextWidth: rootQGCView.defaultTextWidth
property real defaultTextWidth: qgcView.defaultTextWidth
property bool mapped: controller.pitchChannelMapped
property bool reversed: controller.pitchChannelReversed
}
......@@ -343,11 +343,11 @@ QGCView {
id: yawLoader
anchors.left: yawLabel.right
anchors.right: parent.right
height: rootQGCView.defaultTextHeight
height: qgcView.defaultTextHeight
width: 100
sourceComponent: channelMonitorDisplayComponent
property real defaultTextWidth: rootQGCView.defaultTextWidth
property real defaultTextWidth: qgcView.defaultTextWidth
property bool mapped: controller.yawChannelMapped
property bool reversed: controller.yawChannelReversed
}
......@@ -373,11 +373,11 @@ QGCView {
id: throttleLoader
anchors.left: throttleLabel.right
anchors.right: parent.right
height: rootQGCView.defaultTextHeight
height: qgcView.defaultTextHeight
width: 100
sourceComponent: channelMonitorDisplayComponent
property real defaultTextWidth: rootQGCView.defaultTextWidth
property real defaultTextWidth: qgcView.defaultTextWidth
property bool mapped: controller.throttleChannelMapped
property bool reversed: controller.throttleChannelReversed
}
......@@ -418,7 +418,7 @@ QGCView {
onClicked: {
if (text == "Calibrate") {
showDialog(zeroTrimsDialogComponent, dialogTitle, 50, StandardButton.Ok | StandardButton.Cancel)
showDialog(zeroTrimsDialogComponent, dialogTitle, qgcView.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
} else {
controller.nextButtonClicked()
}
......@@ -460,7 +460,7 @@ QGCView {
showBorder: true
text: "Spektrum Bind"
onClicked: showDialog(spektrumBindDialogComponent, dialogTitle, 50, StandardButton.Ok | StandardButton.Cancel)
onClicked: showDialog(spektrumBindDialogComponent, dialogTitle, qgcView.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
}
}
......@@ -468,7 +468,7 @@ QGCView {
showBorder: true
text: "Copy Trims"
visible: QGroundControl.multiVehicleManager.activeVehicle.px4Firmware
onClicked: showDialog(copyTrimsDialogComponent, dialogTitle, 50, StandardButton.Ok | StandardButton.Cancel)
onClicked: showDialog(copyTrimsDialogComponent, dialogTitle, qgcView.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
}
} // Column - Left Column
......@@ -552,11 +552,11 @@ QGCView {
Loader {
id: theLoader
anchors.verticalCenter: channelLabel.verticalCenter
height: rootQGCView.defaultTextHeight
height: qgcView.defaultTextHeight
width: 200
sourceComponent: channelMonitorDisplayComponent
property real defaultTextWidth: rootQGCView.defaultTextWidth
property real defaultTextWidth: qgcView.defaultTextWidth
property bool mapped: true
readonly property bool reversed: false
}
......
......@@ -120,6 +120,10 @@ RadioComponentController::RadioComponentController(void) :
connect(_vehicle, &Vehicle::rcChannelsChanged, this, &RadioComponentController::_rcChannelsChanged);
_loadSettings();
// APM Stack has a bug where some RC params are missing. We need to know what these are so we can skip them if missing
// instead of popping missing param warnings.
_apmPossibleMissingRCChannelParams << 9 << 11 << 12 << 13 << 14;
_resetInternalCalibrationValues();
}
......@@ -704,17 +708,20 @@ void RadioComponentController::_resetInternalCalibrationValues(void)
QVariant value;
enum rcCalFunctions curFunction = rgFlightModeFunctions[i];
bool ok;
int switchChannel = getParameterFact(FactSystem::defaultComponentId, _functionInfo()[curFunction].parameterName)->rawValue().toInt(&ok);
Q_ASSERT(ok);
Fact* paramFact = getParameterFact(FactSystem::defaultComponentId, _functionInfo()[curFunction].parameterName);
if (paramFact) {
bool ok;
int switchChannel = paramFact->rawValue().toInt(&ok);
Q_ASSERT(ok);
// Parameter: 1-based channel, 0=not mapped
// _rgFunctionChannelMapping: 0-based channel, _chanMax=not mapped
// Parameter: 1-based channel, 0=not mapped
// _rgFunctionChannelMapping: 0-based channel, _chanMax=not mapped
if (switchChannel != 0) {
qCDebug(RadioComponentControllerLog) << "Reserving 0-based switch channel" << switchChannel - 1;
_rgFunctionChannelMapping[curFunction] = switchChannel - 1;
_rgChannelInfo[switchChannel - 1].function = curFunction;
if (switchChannel != 0) {
qCDebug(RadioComponentControllerLog) << "Reserving 0-based switch channel" << switchChannel - 1;
_rgFunctionChannelMapping[curFunction] = switchChannel - 1;
_rgChannelInfo[switchChannel - 1].function = curFunction;
}
}
}
}
......@@ -747,20 +754,43 @@ void RadioComponentController::_setInternalCalibrationValuesFromParameters(void)
for (int i = 0; i < _chanMax(); ++i) {
struct ChannelInfo* info = &_rgChannelInfo[i];
if (_px4Vehicle() && _apmPossibleMissingRCChannelParams.contains(i+1)) {
if (!parameterExists(FactSystem::defaultComponentId, minTpl.arg(i+1))) {
// Parameter is missing from this version of APM
info->rcTrim = 1500;
info->rcMin = 1100;
info->rcMax = 1900;
info->reversed = false;
continue;
}
}
info->rcTrim = getParameterFact(FactSystem::defaultComponentId, trimTpl.arg(i+1))->rawValue().toInt(&convertOk);
Q_ASSERT(convertOk);
Fact* paramFact = getParameterFact(FactSystem::defaultComponentId, trimTpl.arg(i+1));
if (paramFact) {
info->rcTrim = paramFact->rawValue().toInt(&convertOk);
Q_ASSERT(convertOk);
}
info->rcMin = getParameterFact(FactSystem::defaultComponentId, minTpl.arg(i+1))->rawValue().toInt(&convertOk);
Q_ASSERT(convertOk);
paramFact = getParameterFact(FactSystem::defaultComponentId, minTpl.arg(i+1));
if (paramFact) {
info->rcMin = paramFact->rawValue().toInt(&convertOk);
Q_ASSERT(convertOk);
}
info->rcMax = getParameterFact(FactSystem::defaultComponentId, maxTpl.arg(i+1))->rawValue().toInt(&convertOk);
Q_ASSERT(convertOk);
paramFact = getParameterFact(FactSystem::defaultComponentId, maxTpl.arg(i+1));
if (paramFact) {
info->rcMax = getParameterFact(FactSystem::defaultComponentId, maxTpl.arg(i+1))->rawValue().toInt(&convertOk);
Q_ASSERT(convertOk);
}
float floatReversed = getParameterFact(FactSystem::defaultComponentId, revTpl.arg(i+1))->rawValue().toFloat(&convertOk);
Q_ASSERT(convertOk);
Q_ASSERT(floatReversed == 1.0f || floatReversed == -1.0f);
info->reversed = floatReversed == -1.0f;
paramFact = getParameterFact(FactSystem::defaultComponentId, revTpl.arg(i+1));
if (paramFact) {
float floatReversed = paramFact->rawValue().toFloat(&convertOk);
Q_ASSERT(convertOk);
Q_ASSERT(floatReversed == 1.0f || floatReversed == -1.0f);
info->reversed = floatReversed == -1.0f;
}
}
for (int i=0; i<rcCalFunctionMax; i++) {
......@@ -768,12 +798,15 @@ void RadioComponentController::_setInternalCalibrationValuesFromParameters(void)
const char* paramName = _functionInfo()[i].parameterName;
if (paramName) {
paramChannel = getParameterFact(FactSystem::defaultComponentId, paramName)->rawValue().toInt(&convertOk);
Q_ASSERT(convertOk);
if (paramChannel != 0) {
_rgFunctionChannelMapping[i] = paramChannel - 1;
_rgChannelInfo[paramChannel - 1].function = (enum rcCalFunctions)i;
Fact* paramFact = getParameterFact(FactSystem::defaultComponentId, paramName);
if (paramFact) {
paramChannel = paramFact->rawValue().toInt(&convertOk);
Q_ASSERT(convertOk);
if (paramChannel != 0) {
_rgFunctionChannelMapping[i] = paramChannel - 1;
_rgChannelInfo[paramChannel - 1].function = (enum rcCalFunctions)i;
}
}
}
}
......@@ -837,7 +870,9 @@ void RadioComponentController::_writeCalibration(void)
{
if (!_uas) return;
_uas->stopCalibration();
if (_px4Vehicle()) {
_uas->stopCalibration();
}
_validateCalibration();
......@@ -851,9 +886,23 @@ void RadioComponentController::_writeCalibration(void)
struct ChannelInfo* info = &_rgChannelInfo[chan];
int oneBasedChannel = chan + 1;
getParameterFact(FactSystem::defaultComponentId, trimTpl.arg(oneBasedChannel))->setRawValue((float)info->rcTrim);
getParameterFact(FactSystem::defaultComponentId, minTpl.arg(oneBasedChannel))->setRawValue((float)info->rcMin);
getParameterFact(FactSystem::defaultComponentId, maxTpl.arg(oneBasedChannel))->setRawValue((float)info->rcMax);
if (_px4Vehicle() && _apmPossibleMissingRCChannelParams.contains(chan+1) && !parameterExists(FactSystem::defaultComponentId, minTpl.arg(chan+1))) {
// RC parameters for this channel are missing from this version of APM
continue;
}
Fact* paramFact = getParameterFact(FactSystem::defaultComponentId, trimTpl.arg(oneBasedChannel));
if (paramFact) {
paramFact->setRawValue((float)info->rcTrim);
}
paramFact = getParameterFact(FactSystem::defaultComponentId, minTpl.arg(oneBasedChannel));
if (paramFact) {
paramFact->setRawValue((float)info->rcMin);
}
paramFact = getParameterFact(FactSystem::defaultComponentId, maxTpl.arg(oneBasedChannel));
if (paramFact) {
paramFact->setRawValue((float)info->rcMax);
}
// APM has a backwards interpretation of "reversed" on the Pitch control. So be careful.
float reversedParamValue;
......@@ -862,7 +911,10 @@ void RadioComponentController::_writeCalibration(void)
} else {
reversedParamValue = info->reversed ? 1.0f : -1.0f;
}
getParameterFact(FactSystem::defaultComponentId, revTpl.arg(oneBasedChannel))->setRawValue(reversedParamValue);
paramFact = getParameterFact(FactSystem::defaultComponentId, revTpl.arg(oneBasedChannel));
if (paramFact) {
paramFact->setRawValue(reversedParamValue);
}
}
// Write function mapping parameters
......@@ -880,9 +932,12 @@ void RadioComponentController::_writeCalibration(void)
if (paramName) {
Fact* paramFact = getParameterFact(FactSystem::defaultComponentId, _functionInfo()[i].parameterName);
if (paramFact->rawValue().toInt() != paramChannel) {
if (paramFact && paramFact->rawValue().toInt() != paramChannel) {
functionMappingChanged = true;
getParameterFact(FactSystem::defaultComponentId, _functionInfo()[i].parameterName)->setRawValue(paramChannel);
paramFact = getParameterFact(FactSystem::defaultComponentId, _functionInfo()[i].parameterName);
if (paramFact) {
paramFact->setRawValue(paramChannel);
}
}
}
}
......@@ -911,7 +966,9 @@ void RadioComponentController::_startCalibration(void)
_resetInternalCalibrationValues();
// Let the mav known we are starting calibration. This should turn off motors and so forth.
_uas->startCalibration(UASInterface::StartCalibrationRadio);
if (_px4Vehicle()) {
_uas->startCalibration(UASInterface::StartCalibrationRadio);
}
_nextButton->setProperty("text", "Next");
_cancelButton->setEnabled(true);
......@@ -926,7 +983,9 @@ void RadioComponentController::_stopCalibration(void)
_currentStep = -1;
if (_uas) {
_uas->stopCalibration();
if (_px4Vehicle()) {
_uas->stopCalibration();
}
_setInternalCalibrationValuesFromParameters();
} else {
_resetInternalCalibrationValues();
......
......@@ -300,6 +300,8 @@ private:
static const int _chanMinimum = 5; ///< Minimum numner of channels required to run
struct ChannelInfo _rgChannelInfo[_chanMaxAny]; ///< Information associated with each rc channel
QList<int> _apmPossibleMissingRCChannelParams; ///< List of possible missing RC*_* params for APM stack
enum rcCalStates _rcCalState; ///< Current calibration state
int _rcCalStateCurrentChannel; ///< Current channel being worked on in rcCalStateIdentify and rcCalStateDetectInversion
......
......@@ -67,7 +67,7 @@ QGCView {
Component.onCompleted: {
if (controller.showCustomConfigPanel) {
showDialog(customConfigDialogComponent, "Custom Airframe Config", 50, StandardButton.Reset)
showDialog(customConfigDialogComponent, "Custom Airframe Config", qgcView.showDialogDefaultWidth, StandardButton.Reset)
}
}
}
......@@ -138,7 +138,7 @@ QGCView {
anchors.right: parent.right
text: "Apply and Restart"
onClicked: showDialog(applyRestartDialogComponent, "Apply and Restart", 50, StandardButton.Apply | StandardButton.Cancel)
onClicked: showDialog(applyRestartDialogComponent, "Apply and Restart", qgcView.showDialogDefaultWidth, StandardButton.Apply | StandardButton.Cancel)
}
}
......
......@@ -35,7 +35,7 @@ import QGroundControl.Controllers 1.0
import QGroundControl.ScreenTools 1.0
QGCView {
id: rootQGCView
id: qgcView
viewPanel: panel
readonly property int monitorThresholdCharWidth: 8 // Character width of Monitor and Threshold labels
......@@ -138,7 +138,7 @@ QGCView {
onTriggered: {
recalcModePositions()
if (rcInMode.value == 1) {
showDialog(joystickEnabledDialogComponent, title, 50, 0)
showDialog(joystickEnabledDialogComponent, title, qgcView.showDialogDefaultWidth, 0)
}
}
}
......
......@@ -34,7 +34,7 @@ import QGroundControl.ScreenTools 1.0
import QGroundControl.Controllers 1.0
QGCView {
id: rootQGCView
id: qgcView
viewPanel: panel
// Help text which is shown both in the status text area prior to pressing a cal button and in the
......@@ -130,7 +130,7 @@ QGCView {
onSetCompassRotations: {
if (showCompass0Rot || showCompass1Rot || showCompass2Rot) {
showDialog(compassRotationDialogComponent, "Set Compass Rotation(s)", 50, StandardButton.Ok)
showDialog(compassRotationDialogComponent, "Set Compass Rotation(s)", qgcView.showDialogDefaultWidth, StandardButton.Ok)
}
}
......@@ -295,7 +295,7 @@ QGCView {
onClicked: {
preCalibrationDialogType = "compass"
preCalibrationDialogHelp = compassHelp
showDialog(preCalibrationDialogComponent, "Calibrate Compass", 50, StandardButton.Cancel | StandardButton.Ok)
showDialog(preCalibrationDialogComponent, "Calibrate Compass", qgcView.showDialogDefaultWidth, StandardButton.Cancel | StandardButton.Ok)
}
}
......@@ -308,7 +308,7 @@ QGCView {
onClicked: {
preCalibrationDialogType = "gyro"
preCalibrationDialogHelp = gyroHelp
showDialog(preCalibrationDialogComponent, "Calibrate Gyro", 50, StandardButton.Cancel | StandardButton.Ok)
showDialog(preCalibrationDialogComponent, "Calibrate Gyro", qgcView.showDialogDefaultWidth, StandardButton.Cancel | StandardButton.Ok)
}
}
......@@ -321,7 +321,7 @@ QGCView {
onClicked: {
preCalibrationDialogType = "accel"
preCalibrationDialogHelp = accelHelp
showDialog(preCalibrationDialogComponent, "Calibrate Accelerometer", 50, StandardButton.Cancel | StandardButton.Ok)
showDialog(preCalibrationDialogComponent, "Calibrate Accelerometer", qgcView.showDialogDefaultWidth, StandardButton.Cancel | StandardButton.Ok)
}
}
......@@ -335,7 +335,7 @@ QGCView {
onClicked: {
preCalibrationDialogType = "level"
preCalibrationDialogHelp = levelHelp
showDialog(preCalibrationDialogComponent, "Level Horizon", 50, StandardButton.Cancel | StandardButton.Ok)
showDialog(preCalibrationDialogComponent, "Level Horizon", qgcView.showDialogDefaultWidth, StandardButton.Cancel | StandardButton.Ok)
}
}
......@@ -349,7 +349,7 @@ QGCView {
onClicked: {
preCalibrationDialogType = "airspeed"
preCalibrationDialogHelp = airspeedHelp
showDialog(preCalibrationDialogComponent, "Calibrate Airspeed", 50, StandardButton.Cancel | StandardButton.Ok)
showDialog(preCalibrationDialogComponent, "Calibrate Airspeed", qgcView.showDialogDefaultWidth, StandardButton.Cancel | StandardButton.Ok)
}
}
......
......@@ -29,7 +29,7 @@ QGCTextField {
fact.value = text
} else {
_validateString = text
qgcView.showDialog(editorDialogComponent, "Invalid Parameter Value", 50, StandardButton.Save)
qgcView.showDialog(editorDialogComponent, "Invalid Parameter Value", qgcView.showDialogDefaultWidth, StandardButton.Save)
}
} else {
fact.value = text
......
......@@ -335,12 +335,18 @@ void ParameterLoader::_determineDefaultComponentId(void)
// the set of parameters. Better than nothing!
_defaultComponentId = -1;
int largestCompParamCount = 0;
foreach(int componentId, _mapParameterName2Variant.keys()) {
if (_mapParameterName2Variant[componentId].count() > _defaultComponentId) {
int compParamCount = _mapParameterName2Variant[componentId].count();
if (compParamCount > largestCompParamCount) {
largestCompParamCount = compParamCount;
_defaultComponentId = componentId;
}
}
Q_ASSERT(_defaultComponentId != -1);
if (_defaultComponentId == -1) {
qWarning() << "All parameters missing, unable to determine default componet id";
}
}
}
......
......@@ -28,6 +28,7 @@
#include "Generic/GenericFirmwarePlugin.h"
#include "AutoPilotPlugins/APM/APMAutoPilotPlugin.h" // FIXME: Hack
#include "QGCMAVLink.h"
#include "QGCApplication.h"
QGC_LOGGING_CATEGORY(APMFirmwarePluginLog, "APMFirmwarePluginLog")
......@@ -211,7 +212,7 @@ int APMFirmwarePlugin::manualControlReservedButtonCount(void)
return -1;
}
void APMFirmwarePlugin::adjustMavlinkMessage(mavlink_message_t* message)
void APMFirmwarePlugin::adjustMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message)
{
if (message->msgid == MAVLINK_MSG_ID_PARAM_VALUE) {
mavlink_param_value_t paramValue;
......@@ -296,9 +297,6 @@ void APMFirmwarePlugin::adjustMavlinkMessage(mavlink_message_t* message)
mavlink_statustext_t statusText;
mavlink_msg_statustext_decode(message, &statusText);
// APM user facing calibration messages come through as high severity, we need to parse them out
// and lower the severity on them so that they don't pop in the users face.
if (!_firmwareVersion.isValid() || statusText.severity < MAV_SEVERITY_NOTICE) {
QByteArray b;
b.resize(MAVLINK_MSG_STATUSTEXT_FIELD_TEXT_LEN+1);
......@@ -314,9 +312,42 @@ void APMFirmwarePlugin::adjustMavlinkMessage(mavlink_message_t* message)
// found version string
_firmwareVersion = APMFirmwareVersion(messageText);
_textSeverityAdjustmentNeeded = _isTextSeverityAdjustmentNeeded(_firmwareVersion);
if (!_firmwareVersion.isBeta() && !_firmwareVersion.isDev()) {
int supportedMajorNumber = -1;
int supportedMinorNumber = -1;
switch (vehicle->vehicleType()) {
case MAV_TYPE_FIXED_WING:
supportedMajorNumber = 3;
supportedMinorNumber = 4;
break;
case MAV_TYPE_QUADROTOR:
case MAV_TYPE_COAXIAL:
case MAV_TYPE_HELICOPTER:
case MAV_TYPE_SUBMARINE:
case MAV_TYPE_HEXAROTOR:
case MAV_TYPE_OCTOROTOR:
case MAV_TYPE_TRICOPTER:
supportedMajorNumber = 3;
supportedMinorNumber = 3;
break;
default:
break;
}
if (supportedMajorNumber != -1) {
if (_firmwareVersion.majorNumber() < supportedMajorNumber || _firmwareVersion.minorNumber() < supportedMinorNumber) {
qgcApp()->showMessage(QString("QGroundControl fully supports Version %1.%2 and above. You are using a version prior to that. This combination is untested, you may run into unpredictable results.").arg(supportedMajorNumber).arg(supportedMinorNumber));
}
}
}
}
}
// APM user facing calibration messages come through as high severity, we need to parse them out
// and lower the severity on them so that they don't pop in the users face.
if (messageText.contains("Place vehicle") || messageText.contains("Calibration successful")) {
_adjustCalibrationMessageSeverity(message);
return;
......
......@@ -86,7 +86,7 @@ public:
virtual QString flightMode(uint8_t base_mode, uint32_t custom_mode);
virtual bool setFlightMode(const QString& flightMode, uint8_t* base_mode, uint32_t* custom_mode);
virtual int manualControlReservedButtonCount(void);
virtual void adjustMavlinkMessage(mavlink_message_t* message);
virtual void adjustMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message);
virtual void initializeVehicle(Vehicle* vehicle);
virtual bool sendHomePositionToVehicle(void);
virtual void addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType);
......
......@@ -90,8 +90,9 @@ public:
/// Called before any mavlink message is processed by Vehicle such taht the firmwre plugin
/// can adjust any message characteristics. This is handy to adjust or differences in mavlink
/// spec implementations such that the base code can remain mavlink generic.
/// @param vehicle Vehicle message came from
/// @param message[in,out] Mavlink message to adjust if needed.
virtual void adjustMavlinkMessage(mavlink_message_t* message) = 0;
virtual void adjustMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message) = 0;
/// Called when Vehicle is first created to send any necessary mavlink messages to the firmware.
virtual void initializeVehicle(Vehicle* vehicle) = 0;
......
......@@ -90,8 +90,9 @@ int GenericFirmwarePlugin::manualControlReservedButtonCount(void)
return -1;
}
void GenericFirmwarePlugin::adjustMavlinkMessage(mavlink_message_t* message)
void GenericFirmwarePlugin::adjustMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message)
{
Q_UNUSED(vehicle);
Q_UNUSED(message);
// Generic plugin does no message adjustment
......
......@@ -42,7 +42,7 @@ public:
virtual QString flightMode(uint8_t base_mode, uint32_t custom_mode);
virtual bool setFlightMode(const QString& flightMode, uint8_t* base_mode, uint32_t* custom_mode);
virtual int manualControlReservedButtonCount(void);
virtual void adjustMavlinkMessage(mavlink_message_t* message);
virtual void adjustMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message);
virtual void initializeVehicle(Vehicle* vehicle);
virtual bool sendHomePositionToVehicle(void);
virtual void addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType);
......
......@@ -177,8 +177,9 @@ int PX4FirmwarePlugin::manualControlReservedButtonCount(void)
return 0; // 0 buttons reserved for rc switch simulation
}
void PX4FirmwarePlugin::adjustMavlinkMessage(mavlink_message_t* message)
void PX4FirmwarePlugin::adjustMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message)
{
Q_UNUSED(vehicle);
Q_UNUSED(message);
// PX4 Flight Stack plugin does no message adjustment
......@@ -217,6 +218,8 @@ QList<MAV_CMD> PX4FirmwarePlugin::supportedMissionCommands(void)
<< MAV_CMD_NAV_RETURN_TO_LAUNCH << MAV_CMD_NAV_LAND << MAV_CMD_NAV_TAKEOFF
<< MAV_CMD_NAV_ROI
<< MAV_CMD_DO_JUMP
<< MAV_CMD_CONDITION_DELAY;
<< MAV_CMD_CONDITION_DELAY
<< MAV_CMD_DO_VTOL_TRANSITION
<< MAV_CMD_DO_DIGICAM_CONTROL;
return list;
}
......@@ -42,7 +42,7 @@ public:
virtual QString flightMode(uint8_t base_mode, uint32_t custom_mode);
virtual bool setFlightMode(const QString& flightMode, uint8_t* base_mode, uint32_t* custom_mode);
virtual int manualControlReservedButtonCount(void);
virtual void adjustMavlinkMessage(mavlink_message_t* message);
virtual void adjustMavlinkMessage(Vehicle* vehicle, mavlink_message_t* message);
virtual void initializeVehicle(Vehicle* vehicle);
virtual bool sendHomePositionToVehicle(void);
virtual void addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType);
......
......@@ -553,7 +553,7 @@
{
"id": 222,
"rawName": "MAV_CMD_DO_GUIDED_LIMITS",
"friendlyName": "Exetrnal control limits",
"friendlyName": "External control limits",
"description": "Set limits for external control",
"param1": {
"label": "Timeout:",
......@@ -588,7 +588,20 @@
{ "id": 2500, "rawName": "MAV_CMD_VIDEO_START_CAPTURE", "friendlyName": "MAV_CMD_VIDEO_START_CAPTURE" },
{ "id": 2501, "rawName": "MAV_CMD_VIDEO_STOP_CAPTURE", "friendlyName": "MAV_CMD_VIDEO_STOP_CAPTURE" },
{ "id": 2800, "rawName": "MAV_CMD_PANORAMA_CREATE", "friendlyName": "MAV_CMD_PANORAMA_CREATE" },
{ "id": 3000, "rawName": "MAV_CMD_DO_VTOL_TRANSITION", "friendlyName": "MAV_CMD_DO_VTOL_TRANSITION" },
{
"id": 3000,
"rawName": "MAV_CMD_DO_VTOL_TRANSITION",
"friendlyName": "VTOL Transition",
"description": "Perform flight mode transition",
"category": "Basic",
"param7": {
"label": "Mode:",
"default": 3,
"decimalPlaces": 0,
"enumStrings": "Hover Mode,Plane Mode",
"enumValues": "3,4"
}
},
{ "id": 30001, "rawName": "MAV_CMD_PAYLOAD_PREPARE_DEPLOY", "friendlyName": "MAV_CMD_PAYLOAD_PREPARE_DEPLOY" },
{ "id": 30002, "rawName": "MAV_CMD_PAYLOAD_CONTROL_DEPLOY", "friendlyName": "MAV_CMD_PAYLOAD_CONTROL_DEPLOY" }
]
......
......@@ -36,7 +36,6 @@ QGCDockWidget::QGCDockWidget(const QString& title, QAction* action, QWidget* par
if (action) {
setWindowTitle(title);
setWindowFlags(Qt::Tool);
loadSettings();
}
}
......@@ -55,11 +54,11 @@ void QGCDockWidget::loadSettings(void)
{
if (_action) {
QSettings settings;
settings.beginGroup(_settingsGroup);
if (settings.contains(_title)) {
restoreGeometry(settings.value(_title).toByteArray());
}
settings.endGroup();
}
}
......@@ -67,8 +66,8 @@ void QGCDockWidget::saveSettings(void)
{
if (_action) {
QSettings settings;
settings.beginGroup(_settingsGroup);
settings.setValue(_title, saveGeometry());
settings.endGroup();
}
}
......@@ -49,7 +49,7 @@ QColor QGCPalette::_windowShadeDark[QGCPalette::_cThemes][QGCPalette::_cColorGro
};
QColor QGCPalette::_text[QGCPalette::_cThemes][QGCPalette::_cColorGroups] = {
{ QColor("#cccccc"), QColor("#000000") },
{ QColor("#9d9d9d"), QColor("#000000") },
{ QColor(0x58, 0x58, 0x58), QColor(0xFF, 0xFF, 0xFF) }
};
......@@ -64,12 +64,12 @@ QColor QGCPalette::_button[QGCPalette::_cThemes][QGCPalette::_cColorGroups] = {
};
QColor QGCPalette::_buttonText[QGCPalette::_cThemes][QGCPalette::_cColorGroups] = {
{ QColor("#dedede"), QColor("#000000") },
{ QColor("#9d9d9d"), QColor("#000000") },
{ QColor(0x2c, 0x2c, 0x2c), QColor(0xFF, 0xFF, 0xFF) },
};
QColor QGCPalette::_buttonHighlight[QGCPalette::_cThemes][QGCPalette::_cColorGroups] = {
{ QColor("#e4e4e4"), QColor("#e4e4e4") },
{ QColor("#e4e4e4"), QColor("#91d1e4") },
{ QColor(0x58, 0x58, 0x58), QColor(237, 235, 51) },
};
......
......@@ -95,7 +95,7 @@ Rectangle {
MenuItem {
text: "Delete all"
onTriggered: qgcView.showDialog(deleteAllPromptDialog, "Delete all", 40, StandardButton.Yes | StandardButton.No)
onTriggered: qgcView.showDialog(deleteAllPromptDialog, "Delete all", qgcView.showDialogDefaultWidth, StandardButton.Yes | StandardButton.No)
}
MenuSeparator { }
......@@ -139,7 +139,7 @@ Rectangle {
}
}
onClicked: qgcView.showDialog(commandDialog, "Select Mission Command", 40, StandardButton.Cancel)
onClicked: qgcView.showDialog(commandDialog, "Select Mission Command", qgcView.showDialogDefaultWidth, StandardButton.Cancel)
}
QGCLabel {
......
......@@ -119,7 +119,7 @@ QGCView {
}
MenuItem {
text: "Search..."
onTriggered: showDialog(searchDialogComponent, "Parameter Search", 50, StandardButton.Reset | StandardButton.Apply)
onTriggered: showDialog(searchDialogComponent, "Parameter Search", panel.showDialogDefaultWidth, StandardButton.Reset | StandardButton.Apply)
}
MenuSeparator { visible: !ScreenTools.isMobile }
MenuItem {
......@@ -290,7 +290,7 @@ QGCView {
id: valueLabel
width: ScreenTools.defaultFontPixelWidth * 20
color: factRow.modelFact.defaultValueAvailable ? (factRow.modelFact.valueEqualsDefault ? __qgcPal.text : __qgcPal.warningText) : __qgcPal.text
text: factRow.modelFact.valueString + " " + factRow.modelFact.units
text: factRow.modelFact.enumStrings.length == 0 ? factRow.modelFact.valueString + " " + factRow.modelFact.units : factRow.modelFact.enumStringValue
}
QGCLabel {
text: factRow.modelFact.shortDescription
......@@ -314,7 +314,7 @@ QGCView {
acceptedButtons: Qt.LeftButton
onClicked: {
__editorDialogFact = factRow.modelFact
showDialog(editorDialogComponent, "Parameter Editor", 50, StandardButton.Cancel | StandardButton.Save)
showDialog(editorDialogComponent, "Parameter Editor", qgcView.showDialogDefaultWidth, StandardButton.Cancel | StandardButton.Save)
}
}
}
......
......@@ -35,6 +35,8 @@ import QGroundControl.FactControls 1.0
import QGroundControl.ScreenTools 1.0
QGCViewDialog {
id: root
property Fact fact
property bool validate: false
property string validateValue
......@@ -42,14 +44,19 @@ QGCViewDialog {
ParameterEditorController { id: controller; factPanel: parent }
function accept() {
var errorString = fact.validate(valueField.text, forceSave.checked)
if (errorString == "") {
fact.value = valueField.text
fact.valueChanged(fact.value)
if (factCombo.visible) {
fact.enumIndex = factCombo.currentIndex
hideDialog()
} else {
validationError.text = errorString
forceSave.visible = true
var errorString = fact.validate(valueField.text, forceSave.checked)
if (errorString == "") {
fact.value = valueField.text
fact.valueChanged(fact.value)
hideDialog()
} else {
validationError.text = errorString
forceSave.visible = true
}
}
}
......@@ -80,14 +87,30 @@ QGCViewDialog {
}
QGCTextField {
id: valueField
text: validate ? validateValue : fact.valueString
id: valueField
text: validate ? validateValue : fact.valueString
visible: fact.enumStrings.length == 0 || validate
//focus: true
// At this point all Facts are numeric
inputMethodHints: Qt.ImhFormattedNumbersOnly
}
QGCComboBox {
id: factCombo
width: valueField.width
visible: fact.enumStrings.length != 0 && !validate
model: fact.enumStrings
Component.onCompleted: {
// We can't bind directly to fact.enumIndex since that would add an unknown value
// if there are no enum strings.
if (visible) {
currentIndex = fact.enumIndex
}
}
}
QGCLabel { text: fact.name }
Row {
......
......@@ -128,8 +128,12 @@ FactPanel {
/// Shows a QGCViewDialog component
/// @param compoent QGCViewDialog component
/// @param title Title for dialog
/// @param charWidth Width of dialog in characters (-1 for full parent width)
/// @param charWidth Width of dialog in characters
/// @param buttons Buttons to show in dialog using StandardButton enum
readonly property int showDialogFullWidth: -1 ///< Use for full width dialog
readonly property int showDialogDefaultWidth: 40 ///< Use for default dialog width
function showDialog(component, title, charWidth, buttons) {
if (__checkForEarlyDialog(title)) {
return
......@@ -158,7 +162,7 @@ FactPanel {
__stopAllAnimations()
__dialogCharWidth = 50
__dialogCharWidth = showDialogDefaultWidth
__dialogTitle = title
__messageDialogText = message
......@@ -285,7 +289,7 @@ FactPanel {
// This is the main dialog panel which is anchored to the right edge
Rectangle {
id: __dialogPanel
width: __dialogCharWidth == -1 ? parent.width : defaultTextWidth * __dialogCharWidth
width: __dialogCharWidth == showDialogFullWidth ? parent.width : defaultTextWidth * __dialogCharWidth
anchors.topMargin: topDialogMargin
anchors.top: parent.top
anchors.bottom: parent.bottom
......
......@@ -221,7 +221,7 @@ void Vehicle::_mavlinkMessageReceived(LinkInterface* link, mavlink_message_t mes
}
// Give the plugin a change to adjust the message contents
_firmwarePlugin->adjustMavlinkMessage(&message);
_firmwarePlugin->adjustMavlinkMessage(this, &message);
switch (message.msgid) {
case MAVLINK_MSG_ID_HOME_POSITION:
......@@ -442,7 +442,7 @@ void Vehicle::_sendMessage(mavlink_message_t message)
MAVLinkProtocol* mavlink = _mavlink;
// Give the plugin a chance to adjust
_firmwarePlugin->adjustMavlinkMessage(&message);
_firmwarePlugin->adjustMavlinkMessage(this, &message);
static const uint8_t messageKeys[256] = MAVLINK_MESSAGE_CRCS;
mavlink_finalize_message_chan(&message, mavlink->getSystemId(), mavlink->getComponentId(), link->getMavlinkChannel(), message.len, messageKeys[message.msgid]);
......
......@@ -109,7 +109,7 @@ QGCView {
// We end up here when we detect a board plugged in after we've started upgrade
statusTextArea.append(highlightPrefix + "Found device" + highlightSuffix + ": " + controller.boardType)
if (controller.boardType == "Pixhawk" || controller.boardType == "AeroCore" || controller.boardType == "PX4 Flow" || controller.boardType == "PX4 FMU V1") {
showDialog(pixhawkFirmwareSelectDialog, title, 50, StandardButton.Ok | StandardButton.Cancel)
showDialog(pixhawkFirmwareSelectDialog, title, qgcView.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
}
}
}
......
......@@ -29,6 +29,5 @@ LogDownload::LogDownload(const QString& title, QAction* action, QWidget *parent)
Q_UNUSED(title);
Q_UNUSED(action);
setSource(QUrl::fromUserInput("qrc:/qml/LogDownload.qml"));
loadSettings();
}
......@@ -113,21 +113,26 @@ LogDownloadController::_logEntry(UASInterface* uas, uint32_t time_utc, uint32_t
return;
}
//-- If this is the first, pre-fill it
if(!_logEntriesModel.count()) {
if(!_logEntriesModel.count() && num_logs > 0) {
for(int i = 0; i < num_logs; i++) {
QGCLogEntry *entry = new QGCLogEntry(i);
_logEntriesModel.append(entry);
}
}
//-- Update this log record
if(id < _logEntriesModel.count()) {
QGCLogEntry* entry = _logEntriesModel[id];
entry->setSize(size);
entry->setTime(QDateTime::fromTime_t(time_utc));
entry->setReceived(true);
entry->setStatus(QString("Available"));
if(num_logs > 0) {
if(id < _logEntriesModel.count()) {
QGCLogEntry* entry = _logEntriesModel[id];
entry->setSize(size);
entry->setTime(QDateTime::fromTime_t(time_utc));
entry->setReceived(true);
entry->setStatus(QString("Available"));
} else {
qWarning() << "Received log entry for out-of-bound index:" << id;
}
} else {
qWarning() << "Received log entry for out-of-bound index:" << id;
//-- No logs to list
_receivedAllEntries();
}
//-- Reset retry count
_retries = 0;
......@@ -515,6 +520,7 @@ LogDownloadController::eraseAll(void)
&msg,
qgcApp()->toolbox()->multiVehicleManager()->activeVehicle()->id(), MAV_COMP_ID_ALL);
_vehicle->sendMessage(msg);
refresh();
}
}
......
......@@ -34,10 +34,10 @@
#include "AutoPilotPlugin.h"
#include "FactPanelController.h"
class MultiVehicleManager;
class UASInterface;
class Vehicle;
class QGCLogEntry;
class MultiVehicleManager;
class UASInterface;
class Vehicle;
class QGCLogEntry;
class LogDownloadData;
Q_DECLARE_LOGGING_CATEGORY(LogDownloadLog)
......
......@@ -131,10 +131,6 @@ public:
/// set into the link when it is added to LinkManager
uint8_t getMavlinkChannel(void) const { Q_ASSERT(_mavlinkChannelSet); return _mavlinkChannel; }
/// @return true: "sh /etc/init.d/rc.usb" must be sent on link to start mavlink
virtual bool requiresUSBMavlinkStart(void) const { return false; }
// These are left unimplemented in order to cause linker errors which indicate incorrect usage of
// connect/disconnect on link directly. All connect/disconnect calls should be made through LinkManager.
bool connect(void);
......
......@@ -189,8 +189,6 @@ void LinkManager::_addLink(LinkInterface* link)
connect(link, &LinkInterface::communicationError, _app, &QGCApplication::criticalMessageBoxOnMainThread);
connect(link, &LinkInterface::bytesReceived, _mavlinkProtocol, &MAVLinkProtocol::receiveBytes);
connect(link, &LinkInterface::connected, _mavlinkProtocol, &MAVLinkProtocol::linkConnected);
connect(link, &LinkInterface::disconnected, _mavlinkProtocol, &MAVLinkProtocol::linkDisconnected);
_mavlinkProtocol->resetMetadataForLink(link);
......
......@@ -173,41 +173,6 @@ void MAVLinkProtocol::resetMetadataForLink(const LinkInterface *link)
currLossCounter[channel] = 0;
}
void MAVLinkProtocol::linkConnected(void)
{
LinkInterface* link = qobject_cast<LinkInterface*>(QObject::sender());
Q_ASSERT(link);
_linkStatusChanged(link, true);
}
void MAVLinkProtocol::linkDisconnected(void)
{
LinkInterface* link = qobject_cast<LinkInterface*>(QObject::sender());
Q_ASSERT(link);
_linkStatusChanged(link, false);
}
void MAVLinkProtocol::_linkStatusChanged(LinkInterface* link, bool connected)
{
qCDebug(MAVLinkProtocolLog) << "_linkStatusChanged" << QString("%1").arg((long)link, 0, 16) << connected;
Q_ASSERT(link);
if (connected) {
if (link->requiresUSBMavlinkStart()) {
// Send command to start MAVLink
// XXX hacky but safe
// Start NSH
const char init[] = {0x0d, 0x0d, 0x0d, 0x0d};
link->writeBytes(init, sizeof(init));
const char* cmd = "sh /etc/init.d/rc.usb\n";
link->writeBytes(cmd, strlen(cmd));
link->writeBytes(init, 4);
}
}
}
/**
* This method parses all incoming bytes and constructs a MAVLink packet.
* It can handle multiple links in parallel, as each link has it's own buffer/
......
......@@ -155,9 +155,6 @@ public slots:
/** @brief Receive bytes from a communication interface */
void receiveBytes(LinkInterface* link, QByteArray b);
void linkConnected(void);
void linkDisconnected(void);
/** @brief Set the rate at which heartbeats are emitted */
void setHeartbeatRate(int rate);
/** @brief Set the system id of this application */
......@@ -285,7 +282,6 @@ private slots:
void _vehicleCountChanged(int count);
private:
void _linkStatusChanged(LinkInterface* link, bool connected);
void _sendMessage(mavlink_message_t message);
void _sendMessage(LinkInterface* link, mavlink_message_t message);
void _sendMessage(LinkInterface* link, mavlink_message_t message, quint8 systemid, quint8 componentid);
......
......@@ -377,15 +377,6 @@ LinkConfiguration* SerialLink::getLinkConfiguration()
return _config;
}
bool SerialLink::requiresUSBMavlinkStart(void) const
{
if (_port) {
return QGCSerialPortInfo(*_port).boardTypePixhawk();
} else {
return false;
}
}
//--------------------------------------------------------------------------
//-- SerialConfiguration
......
......@@ -146,7 +146,6 @@ public:
void requestReset();
bool isConnected() const;
qint64 getConnectionSpeed() const;
bool requiresUSBMavlinkStart(void) const;
// These are left unimplemented in order to cause linker errors which indicate incorrect usage of
// connect/disconnect on link directly. All connect/disconnect calls should be made through LinkManager.
......
......@@ -810,7 +810,8 @@ void UAS::receiveMessage(mavlink_message_t message)
{
case MAV_RESULT_ACCEPTED:
{
emit textMessageReceived(uasId, message.compid, MAV_SEVERITY_INFO, tr("SUCCESS: Executed CMD: %1").arg(ack.command));
// Do not confirm each command positively, as it spams the console.
// emit textMessageReceived(uasId, message.compid, MAV_SEVERITY_INFO, tr("SUCCESS: Executed CMD: %1").arg(ack.command));
}
break;
case MAV_RESULT_TEMPORARILY_REJECTED:
......
......@@ -332,56 +332,59 @@ void MainWindow::_showDockWidget(const QString& name, bool show)
{
// Create the inner widget if we need to
if (!_mapName2DockWidget.contains(name)) {
_createInnerDockWidget(name);
if(!_createInnerDockWidget(name)) {
qWarning() << "Trying to load non existing widget:" << name;
return;
}
}
Q_ASSERT(_mapName2DockWidget.contains(name));
QGCDockWidget* dockWidget = _mapName2DockWidget[name];
Q_ASSERT(dockWidget);
dockWidget->setVisible(show);
Q_ASSERT(_mapName2Action.contains(name));
_mapName2Action[name]->setChecked(show);
}
/// Creates the specified inner dock widget and adds to the QDockWidget
void MainWindow::_createInnerDockWidget(const QString& widgetName)
bool MainWindow::_createInnerDockWidget(const QString& widgetName)
{
QGCDockWidget* widget = NULL;
QAction *action = _mapName2Action[widgetName];
switch(action->data().toInt()) {
case MAVLINK_INSPECTOR:
widget = new QGCMAVLinkInspector(widgetName, action, qgcApp()->toolbox()->mavlinkProtocol(),this);
break;
case CUSTOM_COMMAND:
widget = new CustomCommandWidget(widgetName, action, this);
break;
case ONBOARD_FILES:
widget = new QGCUASFileViewMulti(widgetName, action, this);
break;
case LOG_DOWNLOAD:
widget = new LogDownload(widgetName, action, this);
break;
case STATUS_DETAILS:
widget = new UASInfoWidget(widgetName, action, this);
break;
case HIL_CONFIG:
widget = new HILDockWidget(widgetName, action, this);
break;
case ANALYZE:
widget = new Linecharts(widgetName, action, mavlinkDecoder, this);
break;
case INFO_VIEW:
widget= new QGCTabbedInfoView(widgetName, action, this);
break;
}
if(action->data().toInt() == INFO_VIEW) {
qobject_cast<QGCTabbedInfoView*>(widget)->addSource(mavlinkDecoder);
if(action) {
switch(action->data().toInt()) {
case MAVLINK_INSPECTOR:
widget = new QGCMAVLinkInspector(widgetName, action, qgcApp()->toolbox()->mavlinkProtocol(),this);
break;
case CUSTOM_COMMAND:
widget = new CustomCommandWidget(widgetName, action, this);
break;
case ONBOARD_FILES:
widget = new QGCUASFileViewMulti(widgetName, action, this);
break;
case LOG_DOWNLOAD:
widget = new LogDownload(widgetName, action, this);
break;
case STATUS_DETAILS:
widget = new UASInfoWidget(widgetName, action, this);
break;
case HIL_CONFIG:
widget = new HILDockWidget(widgetName, action, this);
break;
case ANALYZE:
widget = new Linecharts(widgetName, action, mavlinkDecoder, this);
break;
case INFO_VIEW:
widget= new QGCTabbedInfoView(widgetName, action, this);
break;
}
if(action->data().toInt() == INFO_VIEW) {
qobject_cast<QGCTabbedInfoView*>(widget)->addSource(mavlinkDecoder);
}
if(widget) {
_mapName2DockWidget[widgetName] = widget;
}
}
_mapName2DockWidget[widgetName] = widget;
return widget != NULL;
}
void MainWindow::_hideAllDockWidgets(void)
......
......@@ -221,7 +221,7 @@ private:
void _loadCurrentViewState(void);
#ifndef __mobile__
void _createInnerDockWidget(const QString& widgetName);
bool _createInnerDockWidget(const QString& widgetName);
void _buildCommonWidgets(void);
void _hideAllDockWidgets(void);
void _showDockWidget(const QString &name, bool show);
......
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