5 changed files with 0 additions and 1084 deletions
@ -1,247 +0,0 @@
@@ -1,247 +0,0 @@
|
||||
/*=====================================================================
|
||||
|
||||
QGroundControl Open Source Ground Control Station |
||||
|
||||
(c) 2009, 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
|
||||
This file is part of the QGROUNDCONTROL project |
||||
|
||||
QGROUNDCONTROL is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
QGROUNDCONTROL is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
======================================================================*/ |
||||
|
||||
/// @file
|
||||
/// @brief Flight Mode Configuration
|
||||
/// @author Don Gagne <don@thegagnes.com
|
||||
|
||||
#include "FlightModeConfig.h" |
||||
#include "UASManager.h" |
||||
#include "QGCMessageBox.h" |
||||
|
||||
const char* FlightModeConfig::_modeSwitchParam = "RC_MAP_MODE_SW"; |
||||
const char* FlightModeConfig::_manualSwitchParam = "RC_MAP_ACRO_SW"; |
||||
const char* FlightModeConfig::_assistSwitchParam = "RC_MAP_POSCTL_SW"; |
||||
const char* FlightModeConfig::_returnSwitchParam = "RC_MAP_RETURN_SW"; |
||||
const char* FlightModeConfig::_loiterSwitchParam = "RC_MAP_LOITER_SW"; |
||||
|
||||
FlightModeConfig::FlightModeConfig(QWidget *parent) : |
||||
QWidget(parent), |
||||
_mav(NULL), |
||||
_paramMgr(NULL), |
||||
_ui(new Ui::FlightModeConfig) |
||||
{ |
||||
Q_CHECK_PTR(_ui); |
||||
|
||||
_ui->setupUi(this); |
||||
|
||||
// Expectation is that we have an active uas, it is connected and the parameters are ready
|
||||
_mav = UASManager::instance()->getActiveUAS(); |
||||
Q_ASSERT(_mav); |
||||
|
||||
_paramMgr = _mav->getParamManager(); |
||||
Q_ASSERT(_paramMgr); |
||||
Q_ASSERT(_paramMgr->parametersReady()); |
||||
|
||||
_componentId = _paramMgr->getDefaultComponentId(); |
||||
|
||||
connect(_paramMgr, SIGNAL(parameterUpdated(int, QString, QVariant)), this, SLOT(_parameterUpdated(int, QString, QVariant))); |
||||
|
||||
_initUi(); |
||||
} |
||||
|
||||
/// @brief Intialize the UI elements
|
||||
void FlightModeConfig::_initUi(void) { |
||||
struct Combo2Param { |
||||
QGCComboBox* combo; |
||||
QButtonGroup* buttonGroup; |
||||
const char* param; |
||||
const char* description; |
||||
}; |
||||
|
||||
struct Combo2Param rgCombo2ParamMap[] = { |
||||
{ _ui->modeSwitchChannel, _ui->modeSwitchGroup, _modeSwitchParam, "Mode Switch" }, |
||||
{ _ui->manualSwitchChannel, _ui->manualSwitchGroup, _manualSwitchParam, "Manual Switch" }, |
||||
{ _ui->assistSwitchChannel, _ui->assistSwitchGroup, _assistSwitchParam, "Assist Switch" }, |
||||
{ _ui->returnSwitchChannel, _ui->returnSwitchGroup, _returnSwitchParam, "Return Switch" }, |
||||
{ _ui->loiterSwitchChannel, _ui->loiterSwitchGroup, _loiterSwitchParam, "Loiter Switch" }, |
||||
{ NULL, NULL, "RC_MAP_THROTTLE", "Throttle" }, |
||||
{ NULL, NULL, "RC_MAP_YAW", "Rudder" }, |
||||
{ NULL, NULL, "RC_MAP_ROLL", "Aileron" }, |
||||
{ NULL, NULL, "RC_MAP_PITCH", "Elevator" }, |
||||
{ NULL, NULL, "RC_MAP_AUX1", "Aux1" }, |
||||
{ NULL, NULL, "RC_MAP_AUX2", "Aux2" }, |
||||
{ NULL, NULL, "RC_MAP_AUX3", "Aux3" } |
||||
}; |
||||
|
||||
// Setup up maps
|
||||
for (size_t i=0; i<sizeof(rgCombo2ParamMap)/sizeof(rgCombo2ParamMap[0]); i++) { |
||||
struct Combo2Param* map = &rgCombo2ParamMap[i]; |
||||
|
||||
if (map->combo) { |
||||
Q_ASSERT(!_mapChannelCombo2Param.contains(map->combo)); |
||||
_mapChannelCombo2Param[map->combo] = map->param; |
||||
|
||||
Q_ASSERT(!_mapChannelCombo2ButtonGroup.contains(map->combo)); |
||||
_mapChannelCombo2ButtonGroup[map->combo] = map->buttonGroup; |
||||
|
||||
// We connect to activated because we only want signals from user initiated changes
|
||||
connect(map->combo, SIGNAL(activated(int)), this, SLOT(_channelSelected(int))); |
||||
} |
||||
|
||||
Q_ASSERT(!_mapParam2FunctionInfo.contains(map->param)); |
||||
_mapParam2FunctionInfo[map->param] = map->description; |
||||
} |
||||
|
||||
_updateAllSwitches(); |
||||
} |
||||
|
||||
void FlightModeConfig::_updateAllSwitches(void) |
||||
{ |
||||
foreach(QGCComboBox* combo, _mapChannelCombo2Param.keys()) { |
||||
_updateSwitchUiGroup(combo); |
||||
} |
||||
} |
||||
|
||||
/// @brief Selects the channel in the combo for the given parameter
|
||||
void FlightModeConfig::_selectChannelForParam(QGCComboBox* combo, const QString& parameter) |
||||
{ |
||||
int channel = _getChannelMapForParam(parameter); |
||||
|
||||
int index = combo->findData(channel); |
||||
Q_ASSERT(index != -1); |
||||
|
||||
combo->setCurrentIndex(index); |
||||
} |
||||
|
||||
/// @brief Fills a channel selection combo box with channel values
|
||||
void FlightModeConfig::_updateSwitchUiGroup(QGCComboBox* combo) |
||||
{ |
||||
QMap<int, QString> mapChannelUsed2Description; |
||||
|
||||
// Make a map of all channels currently mapped
|
||||
foreach(QString paramId, _mapParam2FunctionInfo.keys()) { |
||||
int channel = _getChannelMapForParam(paramId); |
||||
if (channel != 0) { |
||||
mapChannelUsed2Description[channel] = _mapParam2FunctionInfo[paramId]; |
||||
} |
||||
} |
||||
|
||||
combo->clear(); |
||||
combo->addItem("Disabled", 0); |
||||
for (int i=1; i<=_maxChannels; i++) { |
||||
QString comboText = QString("Channel %1").arg(i); |
||||
|
||||
if (mapChannelUsed2Description.contains(i)) { |
||||
comboText += QString(" (%1)").arg(mapChannelUsed2Description[i]); |
||||
} |
||||
|
||||
combo->addItem(comboText, i); |
||||
} |
||||
|
||||
_selectChannelForParam(combo, _mapChannelCombo2Param[combo]); |
||||
|
||||
// Enable/Disable radio buttons appropriately
|
||||
|
||||
int channelMap = _getChannelMapForParam(_mapChannelCombo2Param[combo]); |
||||
|
||||
Q_ASSERT(_mapChannelCombo2ButtonGroup.contains(combo)); |
||||
Q_ASSERT(_mapChannelCombo2ButtonGroup[combo]->buttons().count() > 0); |
||||
|
||||
foreach(QAbstractButton* button, _mapChannelCombo2ButtonGroup[combo]->buttons()) { |
||||
QRadioButton* radio = qobject_cast<QRadioButton*>(button); |
||||
|
||||
Q_ASSERT(radio); |
||||
|
||||
radio->setEnabled(channelMap != 0); |
||||
} |
||||
} |
||||
|
||||
/// @brief Returns channel mapping for the specified parameters
|
||||
int FlightModeConfig::_getChannelMapForParam(const QString& paramId) |
||||
{ |
||||
QVariant value; |
||||
bool found = _paramMgr->getParameterValue(_componentId, paramId, value); |
||||
Q_UNUSED(found); |
||||
Q_ASSERT(found); |
||||
|
||||
bool conversionOk; |
||||
int channel = value.toInt(&conversionOk); |
||||
Q_UNUSED(conversionOk); |
||||
Q_ASSERT(conversionOk); |
||||
|
||||
return channel; |
||||
} |
||||
|
||||
/// @brief Called when a selection occurs in one of the channel combo boxes
|
||||
void FlightModeConfig::_channelSelected(int requestedMapping) |
||||
{ |
||||
QGCComboBox* combo = qobject_cast<QGCComboBox*>(sender()); |
||||
Q_ASSERT(combo); |
||||
Q_ASSERT(_mapChannelCombo2Param.contains(combo)); |
||||
|
||||
// Check for no-op
|
||||
|
||||
int currentMapping = _getChannelMapForParam(_mapChannelCombo2Param[combo]); |
||||
if (currentMapping == requestedMapping) { |
||||
return; |
||||
} |
||||
|
||||
// Make sure that channel is not already mapped
|
||||
|
||||
if (requestedMapping == 0) { |
||||
// Channel was disabled
|
||||
if (combo == _ui->modeSwitchChannel) { |
||||
// Mode switch is not allowed to be disabled.
|
||||
QGCMessageBox::warning(tr("Flight Mode"), "Mode Switch is a required switch and cannot be disabled."); |
||||
_selectChannelForParam(combo, _mapChannelCombo2Param[combo]); |
||||
return; |
||||
} |
||||
} else { |
||||
// Channel was remapped to a non-disabled channel
|
||||
foreach(QString paramId, _mapParam2FunctionInfo.keys()) { |
||||
int usedChannelMap = _getChannelMapForParam(paramId); |
||||
|
||||
if (requestedMapping == usedChannelMap) { |
||||
QGCMessageBox::warning(tr("Flight Mode"), "You cannot use a channel which is already mapped."); |
||||
_selectChannelForParam(combo, _mapChannelCombo2Param[combo]); |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Save the new setting to the parameter
|
||||
_paramMgr->setParameter(_componentId, _mapChannelCombo2Param[combo], requestedMapping); |
||||
_paramMgr->sendPendingParameters(true, false); |
||||
} |
||||
|
||||
void FlightModeConfig::_parameterUpdated(int componentId, QString parameter, QVariant value) |
||||
{ |
||||
Q_UNUSED(componentId); |
||||
Q_UNUSED(value); |
||||
|
||||
// If this is a function mapping parameter update the combos
|
||||
if (_mapParam2FunctionInfo.contains(parameter)) { |
||||
_updateAllSwitches(); |
||||
} |
||||
|
||||
// Finally if RC Calibration suddenly needs to be re-done disable the entire widget and inform user
|
||||
if (parameter == _modeSwitchParam) { |
||||
// FIXME: Do something more than disable
|
||||
if (isEnabled() == false && value.toInt() != 0) { |
||||
setEnabled(true); |
||||
} else if (isEnabled() == true && value.toInt() == 0) { |
||||
setEnabled(false); |
||||
} |
||||
} |
||||
} |
@ -1,81 +0,0 @@
@@ -1,81 +0,0 @@
|
||||
/*=====================================================================
|
||||
|
||||
QGroundControl Open Source Ground Control Station |
||||
|
||||
(c) 2009, 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
|
||||
This file is part of the QGROUNDCONTROL project |
||||
|
||||
QGROUNDCONTROL is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
QGROUNDCONTROL is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
======================================================================*/ |
||||
|
||||
|
||||
/// @file
|
||||
/// @brief Flight Mode Configuration
|
||||
/// @author Don Gagne <don@thegagnes.com
|
||||
|
||||
#ifndef FlightModeConfig_H |
||||
#define FlightModeConfig_H |
||||
|
||||
#include <QWidget> |
||||
|
||||
#include "UASInterface.h" |
||||
#include "ui_FlightModeConfig.h" |
||||
|
||||
namespace Ui { |
||||
class FlightModeConfig; |
||||
} |
||||
|
||||
|
||||
class FlightModeConfig : public QWidget |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
friend class FlightModeConfigTest; ///< This allows our unit test to access internal information needed.
|
||||
|
||||
public: |
||||
explicit FlightModeConfig(QWidget *parent = 0); |
||||
|
||||
private slots: |
||||
void _channelSelected(int index); |
||||
void _parameterUpdated(int componentId, QString parameter, QVariant value); |
||||
|
||||
private: |
||||
void _initUi(void); |
||||
void _updateSwitchUiGroup(QGCComboBox* combo); |
||||
void _selectChannelForParam(QGCComboBox* combo, const QString& parameter); |
||||
void _updateAllSwitches(void); |
||||
int _getChannelMapForParam(const QString& parameter); |
||||
|
||||
UASInterface* _mav; ///< The current MAV
|
||||
int _componentId; ///< Default component id
|
||||
QGCUASParamManagerInterface* _paramMgr; |
||||
|
||||
static const int _maxChannels = 18; |
||||
|
||||
QMap<QGCComboBox*, QString> _mapChannelCombo2Param; |
||||
QMap<QGCComboBox*, QButtonGroup*> _mapChannelCombo2ButtonGroup; |
||||
QMap<QString, QString> _mapParam2FunctionInfo; |
||||
|
||||
static const char* _modeSwitchParam; |
||||
static const char* _manualSwitchParam; |
||||
static const char* _assistSwitchParam; |
||||
static const char* _returnSwitchParam; |
||||
static const char* _loiterSwitchParam; |
||||
|
||||
Ui::FlightModeConfig* _ui; |
||||
}; |
||||
|
||||
#endif |
@ -1,380 +0,0 @@
@@ -1,380 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<ui version="4.0"> |
||||
<class>FlightModeConfig</class> |
||||
<widget class="QWidget" name="FlightModeConfig"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>0</x> |
||||
<y>0</y> |
||||
<width>642</width> |
||||
<height>645</height> |
||||
</rect> |
||||
</property> |
||||
<property name="sizePolicy"> |
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
||||
<horstretch>0</horstretch> |
||||
<verstretch>0</verstretch> |
||||
</sizepolicy> |
||||
</property> |
||||
<property name="minimumSize"> |
||||
<size> |
||||
<width>642</width> |
||||
<height>645</height> |
||||
</size> |
||||
</property> |
||||
<property name="windowTitle"> |
||||
<string>Form</string> |
||||
</property> |
||||
<layout class="QVBoxLayout" name="verticalLayout"> |
||||
<item> |
||||
<widget class="QLabel" name="label_8"> |
||||
<property name="text"> |
||||
<string>This implementation is a work in progress. Visuals are meant to be functional only. Active display of switch positions is not yet implemented. If this entire screen is disabled, you must do a Radio Calibration before settings Flight Modes.</string> |
||||
</property> |
||||
<property name="wordWrap"> |
||||
<bool>true</bool> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<layout class="QHBoxLayout" name="modeSelectLayout"> |
||||
<item> |
||||
<widget class="QRadioButton" name="multiChannelMode"> |
||||
<property name="text"> |
||||
<string>Flight Modes on multiple channels</string> |
||||
</property> |
||||
<property name="checked"> |
||||
<bool>true</bool> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">modeSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="singleChannelMode"> |
||||
<property name="enabled"> |
||||
<bool>false</bool> |
||||
</property> |
||||
<property name="text"> |
||||
<string>Flight Modes on single channel (coming soon)</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">modeSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<spacer name="horizontalSpacer"> |
||||
<property name="orientation"> |
||||
<enum>Qt::Horizontal</enum> |
||||
</property> |
||||
<property name="sizeHint" stdset="0"> |
||||
<size> |
||||
<width>40</width> |
||||
<height>20</height> |
||||
</size> |
||||
</property> |
||||
</spacer> |
||||
</item> |
||||
</layout> |
||||
</item> |
||||
<item> |
||||
<widget class="QStackedWidget" name="stackedWidget"> |
||||
<property name="sizePolicy"> |
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding"> |
||||
<horstretch>0</horstretch> |
||||
<verstretch>0</verstretch> |
||||
</sizepolicy> |
||||
</property> |
||||
<property name="currentIndex"> |
||||
<number>1</number> |
||||
</property> |
||||
<widget class="QWidget" name="singleChannelWidget"/> |
||||
<widget class="QWidget" name="multiChannelWidget"> |
||||
<layout class="QGridLayout" name="gridLayout"> |
||||
<item row="1" column="0"> |
||||
<layout class="QVBoxLayout" name="verticalLayout_2"> |
||||
<item> |
||||
<widget class="QLabel" name="label_10"> |
||||
<property name="text"> |
||||
<string>Main Mode Switch</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QGCComboBox" name="modeSwitchChannel"/> |
||||
</item> |
||||
<item> |
||||
<widget class="QLabel" name="label_11"> |
||||
<property name="text"> |
||||
<string>Current switch position:</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="manualMode"> |
||||
<property name="text"> |
||||
<string>Manual Mode</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">mainSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="assistMode"> |
||||
<property name="text"> |
||||
<string>Assist Mode</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">mainSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="missionMode"> |
||||
<property name="text"> |
||||
<string>Mission Mode</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">mainSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<spacer name="verticalSpacer_2"> |
||||
<property name="orientation"> |
||||
<enum>Qt::Vertical</enum> |
||||
</property> |
||||
<property name="sizeHint" stdset="0"> |
||||
<size> |
||||
<width>20</width> |
||||
<height>40</height> |
||||
</size> |
||||
</property> |
||||
</spacer> |
||||
</item> |
||||
</layout> |
||||
</item> |
||||
<item row="0" column="1"> |
||||
<layout class="QVBoxLayout" name="verticalLayout_3"> |
||||
<item> |
||||
<widget class="QLabel" name="label_5"> |
||||
<property name="text"> |
||||
<string>Manual Mode Switch</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QGCComboBox" name="manualSwitchChannel"/> |
||||
</item> |
||||
<item> |
||||
<widget class="QLabel" name="label_6"> |
||||
<property name="text"> |
||||
<string>Current switch position:</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="manualAcro"> |
||||
<property name="text"> |
||||
<string>Acro</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">manualSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="manualManual"> |
||||
<property name="text"> |
||||
<string>Manual</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">manualSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="manualStabilize"> |
||||
<property name="text"> |
||||
<string>Stabilize</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">manualSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
</layout> |
||||
</item> |
||||
<item row="1" column="1"> |
||||
<layout class="QVBoxLayout" name="verticalLayout_4"> |
||||
<item> |
||||
<widget class="QLabel" name="label_7"> |
||||
<property name="text"> |
||||
<string>Assist Mode Switch</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QGCComboBox" name="assistSwitchChannel"/> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="altitudeAssist"> |
||||
<property name="text"> |
||||
<string>Altitude Control</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">assistSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="positionAssist"> |
||||
<property name="text"> |
||||
<string>Position Control</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">assistSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<spacer name="verticalSpacer_4"> |
||||
<property name="orientation"> |
||||
<enum>Qt::Vertical</enum> |
||||
</property> |
||||
<property name="sizeHint" stdset="0"> |
||||
<size> |
||||
<width>20</width> |
||||
<height>40</height> |
||||
</size> |
||||
</property> |
||||
</spacer> |
||||
</item> |
||||
</layout> |
||||
</item> |
||||
</layout> |
||||
</widget> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<layout class="QHBoxLayout" name="loiterReturnLayout"> |
||||
<item> |
||||
<layout class="QVBoxLayout" name="loiterLayout"> |
||||
<item> |
||||
<widget class="QLabel" name="label"> |
||||
<property name="text"> |
||||
<string>Loiter Switch</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QGCComboBox" name="loiterSwitchChannel"/> |
||||
</item> |
||||
<item> |
||||
<widget class="QLabel" name="label_3"> |
||||
<property name="text"> |
||||
<string>Current switch position</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="loiterOn"> |
||||
<property name="text"> |
||||
<string>Loiter</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">loiterSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="loiterOff"> |
||||
<property name="text"> |
||||
<string>Off</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">loiterSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
</layout> |
||||
</item> |
||||
<item> |
||||
<layout class="QVBoxLayout" name="returnLayout"> |
||||
<item> |
||||
<widget class="QLabel" name="label_2"> |
||||
<property name="text"> |
||||
<string>Return to Home Switch</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QGCComboBox" name="returnSwitchChannel"/> |
||||
</item> |
||||
<item> |
||||
<widget class="QLabel" name="label_4"> |
||||
<property name="text"> |
||||
<string>Current switch position</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="returnOn"> |
||||
<property name="text"> |
||||
<string>Return to Home</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">returnSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QRadioButton" name="returnOff"> |
||||
<property name="text"> |
||||
<string>Off</string> |
||||
</property> |
||||
<attribute name="buttonGroup"> |
||||
<string notr="true">returnSwitchGroup</string> |
||||
</attribute> |
||||
</widget> |
||||
</item> |
||||
</layout> |
||||
</item> |
||||
</layout> |
||||
</item> |
||||
<item> |
||||
<spacer name="verticalSpacer"> |
||||
<property name="orientation"> |
||||
<enum>Qt::Vertical</enum> |
||||
</property> |
||||
<property name="sizeHint" stdset="0"> |
||||
<size> |
||||
<width>20</width> |
||||
<height>40</height> |
||||
</size> |
||||
</property> |
||||
</spacer> |
||||
</item> |
||||
</layout> |
||||
</widget> |
||||
<customwidgets> |
||||
<customwidget> |
||||
<class>QGCComboBox</class> |
||||
<extends>QComboBox</extends> |
||||
<header>QGCComboBox.h</header> |
||||
</customwidget> |
||||
</customwidgets> |
||||
<resources/> |
||||
<connections/> |
||||
<buttongroups> |
||||
<buttongroup name="returnSwitchGroup"/> |
||||
<buttongroup name="modeSwitchGroup"/> |
||||
<buttongroup name="mainSwitchGroup"/> |
||||
<buttongroup name="loiterSwitchGroup"/> |
||||
<buttongroup name="manualSwitchGroup"/> |
||||
<buttongroup name="assistSwitchGroup"/> |
||||
</buttongroups> |
||||
</ui> |
@ -1,305 +0,0 @@
@@ -1,305 +0,0 @@
|
||||
/*=====================================================================
|
||||
|
||||
QGroundControl Open Source Ground Control Station |
||||
|
||||
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
|
||||
This file is part of the QGROUNDCONTROL project |
||||
|
||||
QGROUNDCONTROL is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
QGROUNDCONTROL is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
======================================================================*/ |
||||
|
||||
#include "FlightModeConfigTest.h" |
||||
#include "UASManager.h" |
||||
#include "MockQGCUASParamManager.h" |
||||
#include "QGCMessageBox.h" |
||||
|
||||
/// @file
|
||||
/// @brief FlightModeConfig Widget unit test
|
||||
///
|
||||
/// @author Don Gagne <don@thegagnes.com>
|
||||
|
||||
// Turned off due to signletonn shutdown sequencing problem. Also since FlightMode config is
|
||||
// being re-written this test will need to be re-written as well.
|
||||
//UT_REGISTER_TEST(FlightModeConfigTest)
|
||||
|
||||
FlightModeConfigTest::FlightModeConfigTest(void) : |
||||
_mockUASManager(NULL), |
||||
_paramMgr(NULL), |
||||
_configWidget(NULL), |
||||
_defaultComponentId(0) |
||||
{ |
||||
|
||||
} |
||||
|
||||
void FlightModeConfigTest::initTestCase(void) |
||||
{ |
||||
|
||||
} |
||||
|
||||
void FlightModeConfigTest::init(void) |
||||
{ |
||||
UnitTest::init(); |
||||
|
||||
_mockUASManager = new MockUASManager(); |
||||
Q_ASSERT(_mockUASManager); |
||||
|
||||
UASManager::setMockInstance(_mockUASManager); |
||||
|
||||
_mockUAS = new MockUAS(); |
||||
Q_CHECK_PTR(_mockUAS); |
||||
_paramMgr = _mockUAS->getParamManager(); |
||||
_defaultComponentId = _paramMgr->getDefaultComponentId(); |
||||
|
||||
_mockUASManager->setMockActiveUAS(_mockUAS); |
||||
|
||||
struct SetupParamInfo { |
||||
const char* param; |
||||
int mappedChannel; |
||||
}; |
||||
|
||||
struct SetupParamInfo rgSetupParamInfo[] = { |
||||
{ "RC_MAP_MODE_SW", 5 }, |
||||
{ "RC_MAP_ACRO_SW", 0 }, |
||||
{ "RC_MAP_POSCTL_SW", 0 }, |
||||
{ "RC_MAP_RETURN_SW", 0 }, |
||||
{ "RC_MAP_LOITER_SW", 0 }, |
||||
{ "RC_MAP_THROTTLE", 1 }, |
||||
{ "RC_MAP_YAW", 2 }, |
||||
{ "RC_MAP_ROLL", 3 }, |
||||
{ "RC_MAP_PITCH", 4 }, |
||||
{ "RC_MAP_AUX1", 0 }, |
||||
{ "RC_MAP_AUX2", 0 }, |
||||
{ "RC_MAP_AUX3", 0 } |
||||
}; |
||||
size_t crgSetupParamInfo = sizeof(rgSetupParamInfo) / sizeof(rgSetupParamInfo[0]); |
||||
|
||||
// Set initial parameter values
|
||||
for (size_t i=0; i<crgSetupParamInfo; i++) { |
||||
struct SetupParamInfo* info = &rgSetupParamInfo[i]; |
||||
|
||||
_paramMgr->setParameter(_defaultComponentId, info->param, info->mappedChannel); |
||||
} |
||||
|
||||
_configWidget = new FlightModeConfig; |
||||
Q_CHECK_PTR(_configWidget); |
||||
|
||||
// Setup combo maps
|
||||
|
||||
struct SetupComboInfo { |
||||
QGCComboBox* combo; |
||||
QButtonGroup* buttonGroup; |
||||
const char* param; |
||||
}; |
||||
|
||||
struct SetupComboInfo rgSetupComboInfo[] = { |
||||
{ _configWidget->_ui->modeSwitchChannel, _configWidget->_ui->modeSwitchGroup, "RC_MAP_MODE_SW" }, |
||||
{ _configWidget->_ui->manualSwitchChannel, _configWidget->_ui->manualSwitchGroup, "RC_MAP_ACRO_SW" }, |
||||
{ _configWidget->_ui->assistSwitchChannel, _configWidget->_ui->assistSwitchGroup, "RC_MAP_POSCTL_SW" }, |
||||
{ _configWidget->_ui->returnSwitchChannel, _configWidget->_ui->returnSwitchGroup, "RC_MAP_RETURN_SW" }, |
||||
{ _configWidget->_ui->loiterSwitchChannel, _configWidget->_ui->loiterSwitchGroup, "RC_MAP_LOITER_SW" } |
||||
}; |
||||
size_t crgSetupComboInfo = sizeof(rgSetupComboInfo) / sizeof(rgSetupComboInfo[0]); |
||||
|
||||
Q_ASSERT(_mapChannelCombo2Param.count() == 0); |
||||
for (size_t i=0; i<crgSetupComboInfo; i++) { |
||||
struct SetupComboInfo* info = &rgSetupComboInfo[i]; |
||||
|
||||
Q_ASSERT(!_mapChannelCombo2Param.contains(info->combo)); |
||||
_mapChannelCombo2Param[info->combo] = info->param; |
||||
|
||||
Q_ASSERT(!_mapChannelCombo2ButtonGroup.contains(info->combo)); |
||||
_mapChannelCombo2ButtonGroup[info->combo] = info->buttonGroup; |
||||
} |
||||
} |
||||
|
||||
void FlightModeConfigTest::cleanup(void) |
||||
{ |
||||
Q_ASSERT(_configWidget); |
||||
delete _configWidget; |
||||
|
||||
Q_ASSERT(_mockUAS); |
||||
delete _mockUAS; |
||||
|
||||
UASManager::setMockInstance(NULL); |
||||
|
||||
Q_ASSERT(_mockUASManager); |
||||
delete _mockUASManager; |
||||
|
||||
_mapChannelCombo2Param.clear(); |
||||
_mapChannelCombo2ButtonGroup.clear(); |
||||
|
||||
UnitTest::cleanup(); |
||||
} |
||||
|
||||
/// @brief Returns channel mapping for the specified parameters
|
||||
int FlightModeConfigTest::_getChannelMapForParam(const QString& paramId) |
||||
{ |
||||
QVariant value; |
||||
bool found = _paramMgr->getParameterValue(_defaultComponentId, paramId, value); |
||||
Q_UNUSED(found); |
||||
Q_ASSERT(found); |
||||
|
||||
bool conversionOk; |
||||
int channel = value.toInt(&conversionOk); |
||||
Q_UNUSED(conversionOk); |
||||
Q_ASSERT(conversionOk); |
||||
|
||||
return channel; |
||||
} |
||||
|
||||
void FlightModeConfigTest::_create_test(void) |
||||
{ |
||||
// This just test widget creation which is handled in init
|
||||
} |
||||
|
||||
void FlightModeConfigTest::_validateInitialState_test(void) |
||||
{ |
||||
// Make sure that the combo boxes are set to the correct selections
|
||||
foreach(QGCComboBox* combo, _mapChannelCombo2Param.keys()) { |
||||
QVariant value; |
||||
|
||||
Q_ASSERT(_mapChannelCombo2Param.contains(combo)); |
||||
int expectedMappedChannel = _getChannelMapForParam(_mapChannelCombo2Param[combo]); |
||||
|
||||
int currentIndex = combo->currentIndex(); |
||||
QVERIFY(currentIndex != -1); |
||||
|
||||
int comboMappedChannel = combo->itemData(currentIndex).toInt(); |
||||
|
||||
QCOMPARE(comboMappedChannel, expectedMappedChannel); |
||||
} |
||||
|
||||
QGCComboBox* combo = _configWidget->_ui->modeSwitchChannel; |
||||
|
||||
// combo should have entry for each channel plus disabled
|
||||
QCOMPARE(combo->count(), _availableChannels + 1); |
||||
|
||||
for (int i=0; i<combo->count(); i++) { |
||||
// Combo data equates to channel mapping value. These are one-base channel values with
|
||||
// 0 meaning disabled. The channel should match the index.
|
||||
QCOMPARE(i, combo->itemData(i).toInt()); |
||||
|
||||
// Channels which are mapped are displayed after the channel number in the form "(name)".
|
||||
// Check for the ending parentheses to indicate mapped channels
|
||||
QString text = combo->itemText(i); |
||||
if (text.endsWith(")")) { |
||||
// Channels 1-5 are mapped
|
||||
QVERIFY(i >= 1 && i <= 5); |
||||
} else { |
||||
QVERIFY(!(i >= 1 && i <= 5)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void FlightModeConfigTest::_validateRCCalCheck_test(void) |
||||
{ |
||||
// Mode switch mapped is used to signal RC Calibration not complete. You must complete RC Cal before
|
||||
// doing Flight Mode Config.
|
||||
|
||||
// Set mode switch mapping to not set
|
||||
Q_ASSERT(_mapChannelCombo2Param.contains(_configWidget->_ui->modeSwitchChannel)); |
||||
_paramMgr->setParameter(_defaultComponentId, _mapChannelCombo2Param[_configWidget->_ui->modeSwitchChannel], 0); |
||||
|
||||
// Widget should disable
|
||||
QCOMPARE(_configWidget->isEnabled(), false); |
||||
|
||||
// Set mode switch mapping to mapped
|
||||
Q_ASSERT(_mapChannelCombo2Param.contains(_configWidget->_ui->modeSwitchChannel)); |
||||
_paramMgr->setParameter(_defaultComponentId, _mapChannelCombo2Param[_configWidget->_ui->modeSwitchChannel], 5); |
||||
|
||||
// Widget should re-enable
|
||||
QCOMPARE(_configWidget->isEnabled(), true); |
||||
} |
||||
|
||||
void FlightModeConfigTest::_attempChannelReuse_test(void) |
||||
{ |
||||
// Attempt to select a channel that is already in use for a switch mapping
|
||||
foreach(QGCComboBox* combo, _mapChannelCombo2Param.keys()) { |
||||
|
||||
Q_ASSERT(_mapChannelCombo2Param.contains(combo)); |
||||
int beforeMapping = _getChannelMapForParam(_mapChannelCombo2Param[combo]); |
||||
|
||||
setExpectedMessageBox(QMessageBox::Ok); |
||||
|
||||
// Channel 1 mapped to throttle. This should pop a message box and the parameter value should
|
||||
// not change.
|
||||
combo->simulateUserSetCurrentIndex(1); |
||||
|
||||
checkExpectedMessageBox(); |
||||
|
||||
int afterMapping = _getChannelMapForParam(_mapChannelCombo2Param[combo]); |
||||
|
||||
QCOMPARE(beforeMapping, afterMapping); |
||||
} |
||||
} |
||||
|
||||
void FlightModeConfigTest::_validateRadioButtonEnableDisable_test(void) |
||||
{ |
||||
// Radio button should enable/disable according to selection
|
||||
foreach(QGCComboBox* combo, _mapChannelCombo2Param.keys()) { |
||||
// Mode switch can't be disabled
|
||||
if (combo == _configWidget->_ui->modeSwitchChannel) { |
||||
continue; |
||||
} |
||||
|
||||
// Index 0 is disabled
|
||||
combo->simulateUserSetCurrentIndex(0); |
||||
|
||||
Q_ASSERT(_mapChannelCombo2ButtonGroup.contains(combo)); |
||||
QButtonGroup* buttonGroup = _mapChannelCombo2ButtonGroup[combo]; |
||||
|
||||
foreach(QAbstractButton* button, buttonGroup->buttons()) { |
||||
QRadioButton* radio = qobject_cast<QRadioButton*>(button); |
||||
Q_ASSERT(radio); |
||||
|
||||
QCOMPARE(radio->isEnabled(), false); |
||||
} |
||||
|
||||
// Index 6 should be a valid mapping
|
||||
combo->simulateUserSetCurrentIndex(6); |
||||
|
||||
foreach(QAbstractButton* button, buttonGroup->buttons()) { |
||||
QRadioButton* radio = qobject_cast<QRadioButton*>(button); |
||||
Q_ASSERT(radio); |
||||
|
||||
QCOMPARE(radio->isEnabled(), true); |
||||
} |
||||
|
||||
// Set back to disabled for next iteration through loop. Otherwise we'll error out
|
||||
// with the channel already in use
|
||||
combo->simulateUserSetCurrentIndex(0); |
||||
} |
||||
} |
||||
|
||||
void FlightModeConfigTest::_validateModeSwitchMustBeEnabled_test(void) |
||||
{ |
||||
QGCComboBox* modeCombo = _configWidget->_ui->modeSwitchChannel; |
||||
|
||||
Q_ASSERT(_mapChannelCombo2Param.contains(modeCombo)); |
||||
int beforeMapping = _getChannelMapForParam(_mapChannelCombo2Param[modeCombo]); |
||||
|
||||
setExpectedMessageBox(QMessageBox::Ok); |
||||
|
||||
// Index 0 is disabled. This should pop a message box and the parameter value should
|
||||
// not change.
|
||||
modeCombo->simulateUserSetCurrentIndex(0); |
||||
|
||||
checkExpectedMessageBox(); |
||||
|
||||
int afterMapping = _getChannelMapForParam(_mapChannelCombo2Param[modeCombo]); |
||||
|
||||
QCOMPARE(beforeMapping, afterMapping); |
||||
} |
@ -1,71 +0,0 @@
@@ -1,71 +0,0 @@
|
||||
/*=====================================================================
|
||||
|
||||
QGroundControl Open Source Ground Control Station |
||||
|
||||
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
|
||||
This file is part of the QGROUNDCONTROL project |
||||
|
||||
QGROUNDCONTROL is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
QGROUNDCONTROL is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
======================================================================*/ |
||||
|
||||
#ifndef FlightModeConfigTest_H |
||||
#define FlightModeConfigTest_H |
||||
|
||||
#include "UnitTest.h" |
||||
#include "MockUASManager.h" |
||||
#include "MockUAS.h" |
||||
#include "AutoPilotPlugins/PX4/FlightModeConfig.h" |
||||
|
||||
/// @file
|
||||
/// @brief FlightModeConfig Widget unit test
|
||||
///
|
||||
/// @author Don Gagne <don@thegagnes.com>
|
||||
|
||||
class FlightModeConfigTest : public UnitTest |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
FlightModeConfigTest(void); |
||||
|
||||
private slots: |
||||
void initTestCase(void); |
||||
void init(void); |
||||
void cleanup(void); |
||||
|
||||
void _create_test(void); |
||||
void _validateInitialState_test(void); |
||||
void _validateRCCalCheck_test(void); |
||||
void _attempChannelReuse_test(void); |
||||
void _validateRadioButtonEnableDisable_test(void); |
||||
void _validateModeSwitchMustBeEnabled_test(void); |
||||
|
||||
private: |
||||
int _getChannelMapForParam(const QString& parameter); |
||||
|
||||
MockUASManager* _mockUASManager; |
||||
MockUAS* _mockUAS; |
||||
QGCUASParamManagerInterface* _paramMgr; |
||||
FlightModeConfig* _configWidget; |
||||
int _defaultComponentId; |
||||
|
||||
QMap<QGCComboBox*, QString> _mapChannelCombo2Param; |
||||
QMap<QGCComboBox*, QButtonGroup*> _mapChannelCombo2ButtonGroup; |
||||
|
||||
static const int _availableChannels = 18; ///< Simulate 18 channel RC Transmitter
|
||||
}; |
||||
|
||||
#endif |
Loading…
Reference in new issue