1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-19 04:52:12 +01:00

LP-467 introduce Child ConfigTaskWidget type

fixes dirty state handling and other issues
This commit is contained in:
Philippe Renon 2017-01-10 08:51:50 +01:00
parent f646ef1d37
commit c8b0787bfb
19 changed files with 343 additions and 312 deletions

View File

@ -69,7 +69,7 @@
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox">
<widget class="QComboBox" name="curve1SourceCombo">
<property name="enabled">
<bool>false</bool>
</property>

View File

@ -245,8 +245,6 @@ ConfigCcpmWidget::ConfigCcpmWidget(QWidget *parent) :
m_aircraft->ccpmType->addItems(Types);
m_aircraft->ccpmType->setCurrentIndex(m_aircraft->ccpmType->count() - 1);
// refreshWidgetsValues(QString("HeliCP"));
connect(m_aircraft->ccpmAngleW, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate()));
connect(m_aircraft->ccpmAngleX, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate()));
connect(m_aircraft->ccpmAngleY, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate()));
@ -284,6 +282,11 @@ ConfigCcpmWidget::~ConfigCcpmWidget()
delete m_aircraft;
}
QString ConfigCcpmWidget::getFrameType()
{
return "HeliCP";
}
void ConfigCcpmWidget::setupUI(QString frameType)
{
Q_UNUSED(frameType);
@ -344,11 +347,9 @@ void ConfigCcpmWidget::enableControls(bool enable)
}
}
void ConfigCcpmWidget::refreshWidgetsValues(QString frameType)
void ConfigCcpmWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
Q_UNUSED(frameType);
setupUI(frameType);
Q_UNUSED(obj);
GUIConfigDataUnion config = getConfigData();
@ -390,13 +391,10 @@ void ConfigCcpmWidget::refreshWidgetsValues(QString frameType)
getMixer();
}
QString ConfigCcpmWidget::updateConfigObjectsFromWidgets()
void ConfigCcpmWidget::updateObjectsFromWidgetsImpl()
{
QString airframeType = updateConfigObjects();
updateConfigObjects();
setMixer();
return airframeType;
}
void ConfigCcpmWidget::UpdateType()
@ -811,17 +809,11 @@ void ConfigCcpmWidget::UpdateMixer()
}
}
QString ConfigCcpmWidget::updateConfigObjects()
void ConfigCcpmWidget::updateConfigObjects()
{
QString airframeType = "HeliCP";
bool useCCPM;
bool useCyclic;
if (updatingFromHardware == true) {
return airframeType;
return;
}
updatingFromHardware = true;
// get the user options
@ -835,8 +827,8 @@ QString ConfigCcpmWidget::updateConfigObjects()
config.heli.ccpmCollectivePassthroughState = m_aircraft->ccpmCollectivePassthrough->isChecked();
config.heli.ccpmLinkCyclicState = m_aircraft->ccpmLinkCyclic->isChecked();
config.heli.ccpmLinkRollState = m_aircraft->ccpmLinkRoll->isChecked();
useCCPM = !(config.heli.ccpmCollectivePassthroughState || !config.heli.ccpmLinkCyclicState);
useCyclic = config.heli.ccpmLinkRollState;
bool useCCPM = !(config.heli.ccpmCollectivePassthroughState || !config.heli.ccpmLinkCyclicState);
bool useCyclic = config.heli.ccpmLinkRollState;
// correction angle
config.heli.CorrectionAngle = m_aircraft->ccpmCorrectionAngle->value();
@ -868,7 +860,6 @@ QString ConfigCcpmWidget::updateConfigObjects()
setConfigData(config);
updatingFromHardware = false;
return airframeType;
}
void ConfigCcpmWidget::SetUIComponentVisibilities()

View File

@ -25,15 +25,11 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef CONFIGccpmWIDGET_H
#define CONFIGccpmWIDGET_H
#ifndef CONFIGCCPMWIDGET_H
#define CONFIGCCPMWIDGET_H
#include "cfg_vehicletypes/vehicleconfig.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "uavobject.h"
class Ui_CcpmConfigWidget;
class QWidget;
@ -62,6 +58,8 @@ public:
ConfigCcpmWidget(QWidget *parent = 0);
~ConfigCcpmWidget();
virtual QString getFrameType();
public slots:
void getMixer();
void setMixer();
@ -71,8 +69,11 @@ protected:
void resizeEvent(QResizeEvent *event);
virtual void enableControls(bool enable);
virtual void refreshWidgetsValues(QString frameType);
virtual QString updateConfigObjectsFromWidgets();
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
virtual void registerWidgets(ConfigTaskWidget &parent);
virtual void setupUI(QString frameType);
private:
Ui_CcpmConfigWidget *m_aircraft;
@ -97,22 +98,20 @@ private:
int MixerChannelData[6];
virtual void registerWidgets(ConfigTaskWidget &parent);
virtual void resetActuators(GUIConfigDataUnion *configData);
void resetActuators(GUIConfigDataUnion *configData);
int ShowDisclaimer(int messageID);
bool updatingFromHardware;
bool updatingToHardware;
QString updateConfigObjects();
void updateConfigObjects();
void saveObjectToSD(UAVObject *obj);
private slots:
virtual void setupUI(QString airframeType);
virtual bool throwConfigError(int typeInt);
bool throwConfigError(int typeInt);
private slots:
void ccpmSwashplateUpdate();
void ccpmSwashplateRedraw();
void UpdateMixer();
@ -130,7 +129,6 @@ private slots:
void enableSwashplateLevellingControl(bool state);
void setSwashplateLevel(int percent);
void SwashLvlSpinBoxChanged(int value);
virtual void refreshValues() {}; // Not used
};
#endif // CONFIGccpmWIDGET_H
#endif // CONFIGCCPMWIDGET_H

View File

@ -29,6 +29,8 @@
#include "ui_airframe_custom.h"
#include "uavobjectmanager.h"
#include "mixersettings.h"
#include <QDebug>
@ -179,6 +181,11 @@ ConfigCustomWidget::~ConfigCustomWidget()
delete m_aircraft;
}
QString ConfigCustomWidget::getFrameType()
{
return "Custom";
}
void ConfigCustomWidget::setupUI(QString frameType)
{
Q_UNUSED(frameType);
@ -190,11 +197,11 @@ void ConfigCustomWidget::registerWidgets(ConfigTaskWidget &parent)
parent.addWidget(m_aircraft->customMixerTable);
parent.addWidget(m_aircraft->customThrottle1Curve->getCurveWidget());
parent.addWidget(m_aircraft->customThrottle1Curve);
// There is no MixerSettings.Curve1Source (i.e. it is always Throttle)
// parent.addWidgetBinding("MixerSettings", "Curve1Source", m_aircraft->curve1SourceCombo);
parent.addWidget(m_aircraft->customThrottle2Curve->getCurveWidget());
parent.addWidget(m_aircraft->customThrottle2Curve);
// TODO why is curve2SourceCombo registered twice ?
parent.addWidgetBinding("MixerSettings", "Curve2Source", m_aircraft->curve2SourceCombo);
parent.addWidget(m_aircraft->curve2SourceCombo);
}
void ConfigCustomWidget::resetActuators(GUIConfigDataUnion *configData)
@ -234,14 +241,13 @@ void ConfigCustomWidget::resetActuators(GUIConfigDataUnion *configData)
/**
Helper function to refresh the UI widget values
*/
void ConfigCustomWidget::refreshWidgetsValues(QString frameType)
void ConfigCustomWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
Q_ASSERT(m_aircraft);
setupUI(frameType);
Q_UNUSED(obj);
UAVDataObject *system = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("SystemSettings")));
Q_ASSERT(system);
QPointer<UAVObjectField> field = system->getField(QString("AirframeType"));
// Do not allow table edit until AirframeType == Custom
@ -314,10 +320,7 @@ void ConfigCustomWidget::refreshWidgetsValues(QString frameType)
}
/**
Helper function to
*/
QString ConfigCustomWidget::updateConfigObjectsFromWidgets()
void ConfigCustomWidget::updateObjectsFromWidgetsImpl()
{
UAVDataObject *system = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("SystemSettings")));
@ -438,7 +441,6 @@ QString ConfigCustomWidget::updateConfigObjectsFromWidgets()
}
setConfigData(configData);
}
return "Custom";
}
/**

View File

@ -29,17 +29,13 @@
#include "cfg_vehicletypes/vehicleconfig.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include <QWidget>
#include <QList>
#include <QItemDelegate>
class Ui_CustomConfigWidget;
class QWidget;
class ConfigCustomWidget : public VehicleConfig {
Q_OBJECT
@ -49,22 +45,24 @@ public:
ConfigCustomWidget(QWidget *parent = 0);
~ConfigCustomWidget();
virtual QString getFrameType();
protected:
void showEvent(QShowEvent *event);
void resizeEvent(QResizeEvent *event);
virtual void refreshWidgetsValues(QString frameType);
virtual QString updateConfigObjectsFromWidgets();
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
virtual void registerWidgets(ConfigTaskWidget &parent);
virtual void setupUI(QString frameType);
private:
Ui_CustomConfigWidget *m_aircraft;
virtual void registerWidgets(ConfigTaskWidget &parent);
virtual void resetActuators(GUIConfigDataUnion *configData);
void resetActuators(GUIConfigDataUnion *configData);
private slots:
virtual void setupUI(QString airframeType);
virtual bool throwConfigError(int numMotors);
bool throwConfigError(int numMotors);
};
class SpinBoxDelegate : public QItemDelegate {

View File

@ -29,6 +29,8 @@
#include "ui_airframe_fixedwing.h"
#include "uavobjectmanager.h"
#include "mixersettings.h"
#include "systemsettings.h"
#include "actuatorsettings.h"
@ -131,7 +133,7 @@ ConfigFixedWingWidget::ConfigFixedWingWidget(QWidget *parent) :
m_aircraft->planeShape->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// Set default model to "Aileron"
connect(m_aircraft->fixedWingType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupUI(QString)));
connect(m_aircraft->fixedWingType, SIGNAL(currentIndexChanged(QString)), this, SLOT(frameTypeChanged(QString)));
m_aircraft->fixedWingType->setCurrentIndex(m_aircraft->fixedWingType->findText("Aileron"));
setupUI(m_aircraft->fixedWingType->currentText());
}
@ -141,6 +143,21 @@ ConfigFixedWingWidget::~ConfigFixedWingWidget()
delete m_aircraft;
}
QString ConfigFixedWingWidget::getFrameType()
{
QString frameType = "FixedWing";
// All airframe types must start with "FixedWing"
if (m_aircraft->fixedWingType->currentText() == "Aileron") {
frameType = "FixedWing";
} else if (m_aircraft->fixedWingType->currentText() == "Elevon") {
frameType = "FixedWingElevon";
} else { // "Vtail"
frameType = "FixedWingVtail";
}
return frameType;
}
/**
Virtual function to setup the UI
*/
@ -343,11 +360,9 @@ void ConfigFixedWingWidget::updateRcCurvesUsed()
/**
Virtual function to refresh the UI widget values
*/
void ConfigFixedWingWidget::refreshWidgetsValues(QString frameType)
void ConfigFixedWingWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
Q_ASSERT(m_aircraft);
setupUI(frameType);
Q_UNUSED(obj);
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(mixer);
@ -390,6 +405,7 @@ void ConfigFixedWingWidget::refreshWidgetsValues(QString frameType)
// Get mixing values for GUI sliders (values stored onboard)
m_aircraft->elevonSlider3->setValue(getMixerValue(mixer, "RollDifferential"));
QString frameType = getFrameType();
if (frameType == "FixedWingElevon" || frameType == "Elevon") {
m_aircraft->elevonSlider1->setValue(getMixerValue(mixer, "MixerValueRoll"));
m_aircraft->elevonSlider2->setValue(getMixerValue(mixer, "MixerValuePitch"));
@ -402,10 +418,8 @@ void ConfigFixedWingWidget::refreshWidgetsValues(QString frameType)
/**
Virtual function to update the UI widget objects
*/
QString ConfigFixedWingWidget::updateConfigObjectsFromWidgets()
void ConfigFixedWingWidget::updateObjectsFromWidgetsImpl()
{
QString airframeType = "FixedWing";
// Save the curve (common to all Fixed wing frames)
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
@ -421,19 +435,14 @@ QString ConfigFixedWingWidget::updateConfigObjectsFromWidgets()
// Set the throttle curve
setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->fixedWingThrottle->getCurve());
// All airframe types must start with "FixedWing"
QString frameType = getFrameType();
if (m_aircraft->fixedWingType->currentText() == "Aileron") {
airframeType = "FixedWing";
setupFrameFixedWing(airframeType);
setupFrameFixedWing(frameType);
} else if (m_aircraft->fixedWingType->currentText() == "Elevon") {
airframeType = "FixedWingElevon";
setupFrameElevon(airframeType);
setupFrameElevon(frameType);
} else { // "Vtail"
airframeType = "FixedWingVtail";
setupFrameVtail(airframeType);
setupFrameVtail(frameType);
}
return airframeType;
}
/**
@ -443,11 +452,11 @@ QString ConfigFixedWingWidget::updateConfigObjectsFromWidgets()
Returns False if impossible to create the mixer.
*/
bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType)
bool ConfigFixedWingWidget::setupFrameFixedWing(QString frameType)
{
// Check coherence:
// Show any config errors in GUI
if (throwConfigError(airframeType)) {
if (throwConfigError(frameType)) {
return false;
}
@ -519,11 +528,11 @@ bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType)
/**
Setup Elevon
*/
bool ConfigFixedWingWidget::setupFrameElevon(QString airframeType)
bool ConfigFixedWingWidget::setupFrameElevon(QString frameType)
{
// Check coherence:
// Show any config errors in GUI
if (throwConfigError(airframeType)) {
if (throwConfigError(frameType)) {
return false;
}
@ -602,11 +611,11 @@ bool ConfigFixedWingWidget::setupFrameElevon(QString airframeType)
/**
Setup VTail
*/
bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType)
bool ConfigFixedWingWidget::setupFrameVtail(QString frameType)
{
// Check coherence:
// Show any config errors in GUI
if (throwConfigError(airframeType)) {
if (throwConfigError(frameType)) {
return false;
}
@ -810,7 +819,7 @@ void ConfigFixedWingWidget::enableControls(bool enable)
/**
This function displays text and color formatting in order to help the user understand what channels have not yet been configured.
*/
bool ConfigFixedWingWidget::throwConfigError(QString airframeType)
bool ConfigFixedWingWidget::throwConfigError(QString frameType)
{
// Initialize configuration error flag
bool error = false;
@ -828,15 +837,15 @@ bool ConfigFixedWingWidget::throwConfigError(QString airframeType)
if (combobox->currentText() == "None") {
int size = combobox->style()->pixelMetric(QStyle::PM_SmallIconSize);
QPixmap pixmap(size, size);
if ((airframeType == "FixedWingElevon") && (i > 2)) {
if ((frameType == "FixedWingElevon") && (i > 2)) {
pixmap.fill(QColor("green"));
// Rudders are optional for elevon frame
combobox->setToolTip(tr("Rudders are optional for Elevon frame"));
} else if (((airframeType == "FixedWing") || (airframeType == "FixedWingVtail")) && (i == 2)) {
} else if (((frameType == "FixedWing") || (frameType == "FixedWingVtail")) && (i == 2)) {
pixmap.fill(QColor("green"));
// Second aileron servo is optional for FixedWing frame
combobox->setToolTip(tr("Second aileron servo is optional"));
} else if ((airframeType == "FixedWing") && (i > 3)) {
} else if ((frameType == "FixedWing") && (i > 3)) {
pixmap.fill(QColor("green"));
// Second elevator and rudders are optional for FixedWing frame
combobox->setToolTip(tr("Second elevator servo is optional"));

View File

@ -29,11 +29,6 @@
#include "cfg_vehicletypes/vehicleconfig.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include <QList>
class Ui_FixedWingConfigWidget;
@ -50,31 +45,33 @@ public:
ConfigFixedWingWidget(QWidget *parent = 0);
~ConfigFixedWingWidget();
private:
Ui_FixedWingConfigWidget *m_aircraft;
QGraphicsSvgItem *planeimg;
virtual void registerWidgets(ConfigTaskWidget &parent);
virtual void resetActuators(GUIConfigDataUnion *configData);
virtual void resetRcOutputs(GUIConfigDataUnion *configData);
bool setupFrameFixedWing(QString airframeType);
bool setupFrameElevon(QString airframeType);
bool setupFrameVtail(QString airframeType);
void setupRcOutputs(QList<QString> rcOutputList);
void updateRcCurvesUsed();
virtual QString getFrameType();
protected:
void resizeEvent(QResizeEvent *);
void showEvent(QShowEvent *);
virtual void enableControls(bool enable);
virtual void refreshWidgetsValues(QString frameType);
virtual QString updateConfigObjectsFromWidgets();
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
private slots:
virtual void setupUI(QString airframeType);
virtual bool throwConfigError(QString airframeType);
virtual void registerWidgets(ConfigTaskWidget &parent);
virtual void setupUI(QString frameType);
private:
Ui_FixedWingConfigWidget *m_aircraft;
QGraphicsSvgItem *planeimg;
void resetActuators(GUIConfigDataUnion *configData);
void resetRcOutputs(GUIConfigDataUnion *configData);
bool setupFrameFixedWing(QString frameType);
bool setupFrameElevon(QString frameType);
bool setupFrameVtail(QString frameType);
void setupRcOutputs(QList<QString> rcOutputList);
void updateRcCurvesUsed();
bool throwConfigError(QString frameType);
};
#endif // CONFIGFIXEDWINGWIDGET_H

View File

@ -29,6 +29,8 @@
#include "ui_airframe_ground.h"
#include "uavobjectmanager.h"
#include "mixersettings.h"
#include "systemsettings.h"
#include "actuatorsettings.h"
@ -88,8 +90,10 @@ ConfigGroundVehicleWidget::ConfigGroundVehicleWidget(QWidget *parent) :
m_aircraft->groundShape->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// Set default model to "Car (Turnable)"
connect(m_aircraft->groundVehicleType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupUI(QString)));
m_aircraft->groundVehicleType->setCurrentIndex(m_aircraft->groundVehicleType->findText("Car (Turnable)"));
connect(m_aircraft->groundVehicleType, SIGNAL(currentIndexChanged(QString)), this, SLOT(frameTypeChanged(QString)));
setupUI(m_aircraft->groundVehicleType->currentText());
}
@ -98,6 +102,25 @@ ConfigGroundVehicleWidget::~ConfigGroundVehicleWidget()
delete m_aircraft;
}
QString ConfigGroundVehicleWidget::getFrameType()
{
QString frameType = "GroundVehicleCar";
// All frame types must start with "GroundVehicle"
if (m_aircraft->groundVehicleType->currentText() == "Boat (Differential)") {
frameType = "GroundVehicleDifferentialBoat";
} else if (m_aircraft->groundVehicleType->currentText() == "Boat (Turnable)") {
frameType = "GroundVehicleBoat";
} else if (m_aircraft->groundVehicleType->currentText() == "Car (Turnable)") {
frameType = "GroundVehicleCar";
} else if (m_aircraft->groundVehicleType->currentText() == "Tank (Differential)") {
frameType = "GroundVehicleDifferential";
} else {
frameType = "GroundVehicleMotorcycle";
}
return frameType;
}
/**
Virtual function to setup the UI
*/
@ -129,7 +152,6 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType)
if (frameType == "GroundVehicleBoat" || frameType == "Boat (Turnable)") {
// Boat
m_vehicleImg->setElementId("boat");
setComboCurrentIndex(m_aircraft->groundVehicleType, m_aircraft->groundVehicleType->findText("Boat (Turnable)"));
m_aircraft->gvMotor1ChannelBox->setEnabled(true);
m_aircraft->gvMotor2ChannelBox->setEnabled(true);
@ -160,20 +182,16 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType)
}
} else if ((frameType == "GroundVehicleDifferential") || (frameType == "Tank (Differential)") ||
(frameType == "GroundVehicleDifferentialBoat") || (frameType == "Boat (Differential)")) {
bool is_Boat = frameType.contains("Boat");
bool isBoat = frameType.contains("Boat");
if (is_Boat) {
if (isBoat) {
// Boat differential
m_vehicleImg->setElementId("boat_diff");
setComboCurrentIndex(m_aircraft->groundVehicleType,
m_aircraft->groundVehicleType->findText("Boat (Differential)"));
m_aircraft->gvSteering1Label->setText("First rudder");
m_aircraft->gvSteering2Label->setText("Second rudder");
} else {
// Tank
m_vehicleImg->setElementId("tank");
setComboCurrentIndex(m_aircraft->groundVehicleType,
m_aircraft->groundVehicleType->findText("Tank (Differential)"));
m_aircraft->gvSteering1Label->setText("Front steering");
m_aircraft->gvSteering2Label->setText("Rear steering");
}
@ -181,7 +199,6 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType)
m_aircraft->gvMotor1ChannelBox->setEnabled(true);
m_aircraft->gvMotor2ChannelBox->setEnabled(true);
m_aircraft->gvMotor1Label->setText("Left motor");
m_aircraft->gvMotor2Label->setText("Right motor");
@ -202,8 +219,8 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType)
initMixerCurves(frameType);
// If new setup, set sliders to defaults and set curves values
if ((!is_Boat && (frameTypeSaved->getValue().toString() != "GroundVehicleDifferential")) ||
(is_Boat && (frameTypeSaved->getValue().toString() != "GroundVehicleDifferentialBoat"))) {
if ((!isBoat && (frameTypeSaved->getValue().toString() != "GroundVehicleDifferential")) ||
(isBoat && (frameTypeSaved->getValue().toString() != "GroundVehicleDifferentialBoat"))) {
m_aircraft->differentialSteeringSlider1->setValue(100);
m_aircraft->differentialSteeringSlider2->setValue(100);
m_aircraft->groundVehicleThrottle1->initLinearCurve(5, 0.8, 0.0);
@ -212,7 +229,6 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType)
} else if (frameType == "GroundVehicleMotorcycle" || frameType == "Motorcycle") {
// Motorcycle
m_vehicleImg->setElementId("motorbike");
setComboCurrentIndex(m_aircraft->groundVehicleType, m_aircraft->groundVehicleType->findText("Motorcycle"));
m_aircraft->gvMotor1ChannelBox->setEnabled(false);
m_aircraft->gvMotor2ChannelBox->setEnabled(true);
@ -244,7 +260,6 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType)
} else {
// Car
m_vehicleImg->setElementId("car");
setComboCurrentIndex(m_aircraft->groundVehicleType, m_aircraft->groundVehicleType->findText("Car (Turnable)"));
m_aircraft->gvMotor1ChannelBox->setEnabled(true);
m_aircraft->gvMotor2ChannelBox->setEnabled(true);
@ -313,9 +328,11 @@ void ConfigGroundVehicleWidget::resetActuators(GUIConfigDataUnion *configData)
/**
Virtual function to refresh the UI widget values
*/
void ConfigGroundVehicleWidget::refreshWidgetsValues(QString frameType)
void ConfigGroundVehicleWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
setupUI(frameType);
Q_UNUSED(obj);
QString frameType = getFrameType();
initMixerCurves(frameType);
@ -374,7 +391,7 @@ void ConfigGroundVehicleWidget::initMixerCurves(QString frameType)
}
}
// Setup all Throttle2 curves for all types of airframes
// Setup all Throttle2 curves for all types of frames
getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, &curveValues);
if (isValidThrottleCurve(&curveValues)) {
@ -394,10 +411,8 @@ void ConfigGroundVehicleWidget::initMixerCurves(QString frameType)
/**
Virtual function to update the UI widget objects
*/
QString ConfigGroundVehicleWidget::updateConfigObjectsFromWidgets()
void ConfigGroundVehicleWidget::updateObjectsFromWidgetsImpl()
{
QString airframeType = "GroundVehicleCar";
// Save the curve (common to all ground vehicle frames)
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
@ -405,25 +420,18 @@ QString ConfigGroundVehicleWidget::updateConfigObjectsFromWidgets()
setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->groundVehicleThrottle1->getCurve());
setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, m_aircraft->groundVehicleThrottle2->getCurve());
// All airframe types must start with "GroundVehicle"
QString frameType = getFrameType();
if (m_aircraft->groundVehicleType->currentText() == "Boat (Differential)") {
airframeType = "GroundVehicleDifferentialBoat";
setupGroundVehicleDifferential(airframeType);
setupGroundVehicleDifferential(frameType);
} else if (m_aircraft->groundVehicleType->currentText() == "Boat (Turnable)") {
airframeType = "GroundVehicleBoat";
setupGroundVehicleTurnable(airframeType);
setupGroundVehicleTurnable(frameType);
} else if (m_aircraft->groundVehicleType->currentText() == "Car (Turnable)") {
airframeType = "GroundVehicleCar";
setupGroundVehicleTurnable(airframeType);
setupGroundVehicleTurnable(frameType);
} else if (m_aircraft->groundVehicleType->currentText() == "Tank (Differential)") {
airframeType = "GroundVehicleDifferential";
setupGroundVehicleDifferential(airframeType);
setupGroundVehicleDifferential(frameType);
} else {
airframeType = "GroundVehicleMotorcycle";
setupGroundVehicleMotorcycle(airframeType);
setupGroundVehicleMotorcycle(frameType);
}
return airframeType;
}
/**
@ -431,11 +439,11 @@ QString ConfigGroundVehicleWidget::updateConfigObjectsFromWidgets()
Returns False if impossible to create the mixer.
*/
bool ConfigGroundVehicleWidget::setupGroundVehicleMotorcycle(QString airframeType)
bool ConfigGroundVehicleWidget::setupGroundVehicleMotorcycle(QString frameType)
{
// Check coherence:
// Show any config errors in GUI
if (throwConfigError(airframeType)) {
if (throwConfigError(frameType)) {
return false;
}
@ -481,12 +489,12 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleMotorcycle(QString airframeTyp
Returns False if impossible to create the mixer.
*/
bool ConfigGroundVehicleWidget::setupGroundVehicleDifferential(QString airframeType)
bool ConfigGroundVehicleWidget::setupGroundVehicleDifferential(QString frameType)
{
// Check coherence:
// Show any config errors in GUI
if (throwConfigError(airframeType)) {
if (throwConfigError(frameType)) {
return false;
}
@ -529,11 +537,11 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleDifferential(QString airframeT
Returns False if impossible to create the mixer.
*/
bool ConfigGroundVehicleWidget::setupGroundVehicleTurnable(QString airframeType)
bool ConfigGroundVehicleWidget::setupGroundVehicleTurnable(QString frameType)
{
// Check coherence:
// Show any config errors in GUI
if (throwConfigError(airframeType)) {
if (throwConfigError(frameType)) {
return false;
}
@ -566,7 +574,7 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleTurnable(QString airframeType)
channel = m_aircraft->gvMotor2ChannelBox->currentIndex() - 1;
setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_REVERSABLEMOTOR);
if (airframeType == "GroundVehicleCar") {
if (frameType == "GroundVehicleCar") {
// Car: Throttle2 curve for 2nd motor
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127);
} else {
@ -582,7 +590,7 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleTurnable(QString airframeType)
/**
This function displays text and color formatting in order to help the user understand what channels have not yet been configured.
*/
bool ConfigGroundVehicleWidget::throwConfigError(QString airframeType)
bool ConfigGroundVehicleWidget::throwConfigError(QString frameType)
{
// Initialize configuration error flag
bool error = false;
@ -593,7 +601,7 @@ bool ConfigGroundVehicleWidget::throwConfigError(QString airframeType)
pixmap.fill(QColor("red"));
if ((airframeType == "GroundVehicleCar") || (airframeType == "GroundVehicleBoat")) { // Car
if ((frameType == "GroundVehicleCar") || (frameType == "GroundVehicleBoat")) { // Car
if (m_aircraft->gvMotor1ChannelBox->currentText() == "None"
&& m_aircraft->gvMotor2ChannelBox->currentText() == "None") {
m_aircraft->gvMotor1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); // Set color palettes
@ -613,7 +621,7 @@ bool ConfigGroundVehicleWidget::throwConfigError(QString airframeType)
m_aircraft->gvSteering1ChannelBox->setItemData(0, 0, Qt::DecorationRole); // Reset color palettes
m_aircraft->gvSteering2ChannelBox->setItemData(0, 0, Qt::DecorationRole); // Reset color palettes
}
} else if (airframeType.contains("GroundVehicleDifferential")) { // differential Tank and Boat
} else if (frameType.contains("GroundVehicleDifferential")) { // differential Tank and Boat
if (m_aircraft->gvMotor1ChannelBox->currentText() == "None"
|| m_aircraft->gvMotor2ChannelBox->currentText() == "None") {
m_aircraft->gvMotor1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); // Set color palettes
@ -627,7 +635,7 @@ bool ConfigGroundVehicleWidget::throwConfigError(QString airframeType)
// Always reset
m_aircraft->gvSteering1ChannelBox->setItemData(0, 0, Qt::DecorationRole); // Reset color palettes
m_aircraft->gvSteering2ChannelBox->setItemData(0, 0, Qt::DecorationRole); // Reset color palettes
} else if (airframeType == "GroundVehicleMotorcycle") { // Motorcycle
} else if (frameType == "GroundVehicleMotorcycle") { // Motorcycle
if (m_aircraft->gvMotor2ChannelBox->currentText() == "None") {
m_aircraft->gvMotor2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); // Set color palettes
error = true;

View File

@ -30,11 +30,6 @@
#include "cfg_vehicletypes/vehicleconfig.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
class Ui_GroundConfigWidget;
class QWidget;
@ -49,6 +44,8 @@ public:
ConfigGroundVehicleWidget(QWidget *parent = 0);
~ConfigGroundVehicleWidget();
virtual QString getFrameType();
virtual void initMixerCurves(QString frameType);
protected:
@ -56,23 +53,23 @@ protected:
void showEvent(QShowEvent *);
virtual void enableControls(bool enable);
virtual void refreshWidgetsValues(QString frameType);
virtual QString updateConfigObjectsFromWidgets();
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
virtual void registerWidgets(ConfigTaskWidget &parent);
virtual void setupUI(QString frameType);
private:
Ui_GroundConfigWidget *m_aircraft;
QGraphicsSvgItem *m_vehicleImg;
virtual void registerWidgets(ConfigTaskWidget &parent);
virtual void resetActuators(GUIConfigDataUnion *configData);
void resetActuators(GUIConfigDataUnion *configData);
bool setupGroundVehicleTurnable(QString airframeType);
bool setupGroundVehicleDifferential(QString airframeType);
bool setupGroundVehicleMotorcycle(QString airframeType);
bool setupGroundVehicleTurnable(QString frameType);
bool setupGroundVehicleDifferential(QString frameType);
bool setupGroundVehicleMotorcycle(QString frameType);
private slots:
virtual void setupUI(QString airframeType);
virtual bool throwConfigError(QString airframeType);
bool throwConfigError(QString frameType);
};
#endif // CONFIGGROUNDVEHICLEWIDGET_H

View File

@ -29,6 +29,8 @@
#include "ui_airframe_multirotor.h"
#include "uavobjectmanager.h"
#include "mixersettings.h"
#include "systemsettings.h"
#include "actuatorsettings.h"
@ -170,7 +172,7 @@ ConfigMultiRotorWidget::ConfigMultiRotorWidget(QWidget *parent) :
// Set default model to "Quad X"
m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Quad X"));
connect(m_aircraft->multirotorFrameType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupUI(QString)));
connect(m_aircraft->multirotorFrameType, SIGNAL(currentIndexChanged(QString)), this, SLOT(frameTypeChanged(QString)));
// Connect the multirotor motor reverse checkbox
connect(m_aircraft->MultirotorRevMixerCheckBox, SIGNAL(clicked(bool)), this, SLOT(reverseMultirotorMotor()));
@ -184,6 +186,38 @@ ConfigMultiRotorWidget::~ConfigMultiRotorWidget()
delete m_aircraft;
}
QString ConfigMultiRotorWidget::getFrameType()
{
QString frameType;
if (m_aircraft->multirotorFrameType->currentText() == "Quad +") {
frameType = "QuadP";
} else if (m_aircraft->multirotorFrameType->currentText() == "Quad X") {
frameType = "QuadX";
} else if (m_aircraft->multirotorFrameType->currentText() == "Hexacopter") {
frameType = "Hexa";
} else if (m_aircraft->multirotorFrameType->currentText() == "Hexacopter X") {
frameType = "HexaX";
} else if (m_aircraft->multirotorFrameType->currentText() == "Hexacopter H") {
frameType = "HexaH";
} else if (m_aircraft->multirotorFrameType->currentText() == "Hexacopter Y6") {
frameType = "HexaCoax";
} else if (m_aircraft->multirotorFrameType->currentText() == "Octocopter") {
frameType = "Octo";
} else if (m_aircraft->multirotorFrameType->currentText() == "Octocopter X") {
frameType = "OctoX";
} else if (m_aircraft->multirotorFrameType->currentText() == "Octocopter V") {
frameType = "OctoV";
} else if (m_aircraft->multirotorFrameType->currentText() == "Octo Coax +") {
frameType = "OctoCoaxP";
} else if (m_aircraft->multirotorFrameType->currentText() == "Octo Coax X") {
frameType = "OctoCoaxX";
} else if (m_aircraft->multirotorFrameType->currentText() == "Tricopter Y") {
frameType = "Tri";
}
return frameType;
}
void ConfigMultiRotorWidget::setupUI(QString frameType)
{
Q_ASSERT(m_aircraft);
@ -433,11 +467,9 @@ void ConfigMultiRotorWidget::updateRcCurvesUsed()
/**
Helper function to refresh the UI widget values
*/
void ConfigMultiRotorWidget::refreshWidgetsValues(QString frameType)
void ConfigMultiRotorWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
Q_ASSERT(m_aircraft);
setupUI(frameType);
Q_UNUSED(obj);
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(mixer);
@ -457,6 +489,7 @@ void ConfigMultiRotorWidget::refreshWidgetsValues(QString frameType)
GUIConfigDataUnion config = getConfigData();
multiGUISettingsStruct multi = config.multi;
QString frameType = getFrameType();
if (frameType == "QuadP") {
// Motors 1/2/3/4 are: N / E / S / W
setComboCurrentIndex(m_aircraft->multiMotorChannelBox1, multi.VTOLMotorN);
@ -583,9 +616,9 @@ void ConfigMultiRotorWidget::updateMotorsPositionLabels(QStringList motorLabels)
}
/**
Helper function to update the UI widget objects
Function to update the UI widget objects
*/
QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
void ConfigMultiRotorWidget::updateObjectsFromWidgetsImpl()
{
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
@ -601,26 +634,19 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
// Curve is also common to all quads:
setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->multiThrottleCurve->getCurve());
QString airframeType;
QList<QString> motorList;
if (m_aircraft->multirotorFrameType->currentText() == "Quad +") {
airframeType = "QuadP";
setupQuad(true);
} else if (m_aircraft->multirotorFrameType->currentText() == "Quad X") {
airframeType = "QuadX";
setupQuad(false);
} else if (m_aircraft->multirotorFrameType->currentText() == "Hexacopter") {
airframeType = "Hexa";
setupHexa(true);
} else if (m_aircraft->multirotorFrameType->currentText() == "Hexacopter X") {
airframeType = "HexaX";
setupHexa(false);
} else if (m_aircraft->multirotorFrameType->currentText() == "Hexacopter H") {
airframeType = "HexaH";
// Show any config errors in GUI
if (throwConfigError(6)) {
return airframeType;
return;
}
motorList << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW";
setupMotors(motorList);
@ -647,11 +673,9 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
setupMultiRotorMixer(hMixer);
m_aircraft->mrStatusLabel->setText(tr("Configuration OK"));
} else if (m_aircraft->multirotorFrameType->currentText() == "Hexacopter Y6") {
airframeType = "HexaCoax";
// Show any config errors in GUI
if (throwConfigError(6)) {
return airframeType;
return;
}
motorList << "VTOLMotorNW" << "VTOLMotorW" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorS" << "VTOLMotorSE";
setupMotors(motorList);
@ -671,11 +695,9 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
setupMultiRotorMixer(mixerMatrix);
m_aircraft->mrStatusLabel->setText(tr("Configuration OK"));
} else if (m_aircraft->multirotorFrameType->currentText() == "Octocopter") {
airframeType = "Octo";
// Show any config errors in GUI
if (throwConfigError(8)) {
return airframeType;
return;
}
motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW"
<< "VTOLMotorW" << "VTOLMotorNW";
@ -702,11 +724,9 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
setupMultiRotorMixer(mixerMatrix);
m_aircraft->mrStatusLabel->setText(tr("Configuration OK"));
} else if (m_aircraft->multirotorFrameType->currentText() == "Octocopter X") {
airframeType = "OctoX";
// Show any config errors in GUI
if (throwConfigError(8)) {
return airframeType;
return;
}
motorList << "VTOLMotorNNE" << "VTOLMotorENE" << "VTOLMotorESE" << "VTOLMotorSSE" << "VTOLMotorSSW" << "VTOLMotorWSW"
<< "VTOLMotorWNW" << "VTOLMotorNNW";
@ -733,11 +753,9 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
setupMultiRotorMixer(mixerMatrix);
m_aircraft->mrStatusLabel->setText(tr("Configuration OK"));
} else if (m_aircraft->multirotorFrameType->currentText() == "Octocopter V") {
airframeType = "OctoV";
// Show any config errors in GUI
if (throwConfigError(8)) {
return airframeType;
return;
}
motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW"
<< "VTOLMotorW" << "VTOLMotorNW";
@ -758,11 +776,9 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
setupMultiRotorMixer(mixerMatrix);
m_aircraft->mrStatusLabel->setText(tr("Configuration OK"));
} else if (m_aircraft->multirotorFrameType->currentText() == "Octo Coax +") {
airframeType = "OctoCoaxP";
// Show any config errors in GUI
if (throwConfigError(8)) {
return airframeType;
return;
}
motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW"
<< "VTOLMotorW" << "VTOLMotorNW";
@ -782,11 +798,9 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
setupMultiRotorMixer(mixerMatrix);
m_aircraft->mrStatusLabel->setText(tr("Configuration OK"));
} else if (m_aircraft->multirotorFrameType->currentText() == "Octo Coax X") {
airframeType = "OctoCoaxX";
// Show any config errors in GUI
if (throwConfigError(8)) {
return airframeType;
return;
}
motorList << "VTOLMotorNW" << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorS"
<< "VTOLMotorSW" << "VTOLMotorW";
@ -806,15 +820,13 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
setupMultiRotorMixer(mixerMatrix);
m_aircraft->mrStatusLabel->setText(tr("Configuration OK"));
} else if (m_aircraft->multirotorFrameType->currentText() == "Tricopter Y") {
airframeType = "Tri";
// Show any config errors in GUI
if (throwConfigError(3)) {
return airframeType;
return;
}
if (m_aircraft->triYawChannelBox->currentText() == "None") {
m_aircraft->mrStatusLabel->setText(tr("<font color='red'>ERROR: Assign a Yaw channel</font>"));
return airframeType;
return;
}
motorList << "VTOLMotorNW" << "VTOLMotorNE" << "VTOLMotorS";
setupMotors(motorList);
@ -850,7 +862,6 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
m_aircraft->mrStatusLabel->setText(tr("Configuration OK"));
}
return airframeType;
}
void ConfigMultiRotorWidget::setYawMixLevel(int value)

View File

@ -29,11 +29,6 @@
#include "cfg_vehicletypes/vehicleconfig.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include <QList>
class Ui_MultiRotorConfigWidget;
@ -51,23 +46,26 @@ public:
ConfigMultiRotorWidget(QWidget *parent = 0);
~ConfigMultiRotorWidget();
virtual QString getFrameType();
protected:
void showEvent(QShowEvent *event);
void resizeEvent(QResizeEvent *event);
virtual void enableControls(bool enable);
virtual void refreshWidgetsValues(QString frameType);
virtual QString updateConfigObjectsFromWidgets();
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
virtual void registerWidgets(ConfigTaskWidget &parent);
virtual void setupUI(QString frameType);
private:
Ui_MultiRotorConfigWidget *m_aircraft;
QGraphicsSvgItem *quad;
bool invertMotors;
virtual void resetActuators(GUIConfigDataUnion *configData);
virtual void resetRcOutputs(GUIConfigDataUnion *configData);
void resetActuators(GUIConfigDataUnion *configData);
void resetRcOutputs(GUIConfigDataUnion *configData);
bool setupQuad(bool pLayout);
bool setupHexa(bool pLayout);
@ -83,10 +81,9 @@ private:
void updateMotorsPositionLabels(QStringList motorLabels);
void setupEnabledControls(QString multiRotorType);
private slots:
virtual void setupUI(QString airframeType);
virtual bool throwConfigError(int numMotors);
bool throwConfigError(int numMotors);
private slots:
void reverseMultirotorMotor();
};

View File

@ -38,7 +38,7 @@
#include <QPushButton>
#include <QPointer>
VehicleConfig::VehicleConfig(QWidget *parent) : ConfigTaskWidget(parent)
VehicleConfig::VehicleConfig(QWidget *parent) : ConfigTaskWidget(parent, Child)
{
// Generate lists of mixerTypeNames, mixerVectorNames, channelNames
channelNames << "None";
@ -105,19 +105,21 @@ void VehicleConfig::setConfigData(GUIConfigDataUnion configData)
}
}
void VehicleConfig::setupUI(QString frameType)
QString VehicleConfig::getFrameType()
{
Q_UNUSED(frameType);
return "None";
}
void VehicleConfig::refreshWidgetsValues(QString frameType)
void VehicleConfig::frameTypeChanged(QString frameType)
{
Q_UNUSED(frameType);
setupUI(frameType);
}
QString VehicleConfig::updateConfigObjectsFromWidgets()
void VehicleConfig::enableControls(bool enable)
{
return NULL;
Q_UNUSED(enable);
// do nothing. no need to call parent.
}
void VehicleConfig::refreshWidgetsValuesImpl(UAVObject *obj)
@ -128,23 +130,16 @@ void VehicleConfig::refreshWidgetsValuesImpl(UAVObject *obj)
void VehicleConfig::updateObjectsFromWidgetsImpl()
{}
void VehicleConfig::resetActuators(GUIConfigDataUnion *configData)
{
Q_UNUSED(configData);
}
void VehicleConfig::enableControls(bool enable)
{
Q_UNUSED(enable);
// do nothing. no need to call parent.
}
void VehicleConfig::registerWidgets(ConfigTaskWidget &parent)
{
Q_UNUSED(parent);
}
void VehicleConfig::setupUI(QString frameType)
{
Q_UNUSED(frameType);
}
// NEW STYLE: Loop through the widgets looking for all widgets that have "ChannelBox" in their name
// The upshot of this is that ALL new ComboBox widgets for selecting the output channel must have "ChannelBox" in their name
// FOR WHATEVER REASON, THIS DOES NOT WORK WITH ChannelBox. ChannelBo is sufficiently accurate

View File

@ -29,11 +29,11 @@
#define VEHICLECONFIG_H
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "actuatorcommand.h"
class UAVDataObject;
typedef struct {
uint VTOLMotorN : 4;
uint VTOLMotorS : 4;
@ -163,12 +163,10 @@ class ConfigVehicleTypeWidget;
* This class handles vehicle specific configuration UI and associated logic.
*
* VehicleConfig derives from ConfigTaskWidget but is not a top level ConfigTaskWidget.
* VehicleConfig objects are nested within the ConfigVehicleConfigWidget and have particularities:
* VehicleConfig objects are nested within the ConfigVehicleTypeWidget and have particularities:
* - bindings are added to the parent (i.e. ConfigVehicleConfigWidget)
* - auto bindings are not supported
* - as a consequence things like dirty state management are bypassed and delegated to the parent class.
*
* It does not use the "dirty" state management directly and registers its relevant widgets with ConfigTaskWidget to do so.
*/
class VehicleConfig : public ConfigTaskWidget {
Q_OBJECT
@ -222,6 +220,8 @@ public:
VehicleConfig(QWidget *parent = 0);
~VehicleConfig();
virtual QString getFrameType();
double getMixerValue(UAVDataObject *mixer, QString elementName);
void setMixerValue(UAVDataObject *mixer, QString elementName, double value);
@ -251,16 +251,13 @@ protected:
virtual void updateObjectsFromWidgetsImpl();
virtual void registerWidgets(ConfigTaskWidget &parent);
virtual void refreshWidgetsValues(QString frameType);
virtual QString updateConfigObjectsFromWidgets();
virtual void setupUI(QString frameType);
protected slots:
void frameTypeChanged(QString frameType);
private:
static UAVObjectManager *getUAVObjectManager();
virtual void resetActuators(GUIConfigDataUnion *configData);
private slots:
virtual void setupUI(QString airframeType);
};
#endif // VEHICLECONFIG_H

View File

@ -43,7 +43,7 @@ static const int MAX_CHANNEL_NUM = 250;
static const int MIN_CHANNEL_RANGE = 10;
static const float FREQUENCY_STEP = 0.040;
ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(parent, false), statusUpdated(false)
ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(parent, OPLink), statusUpdated(false)
{
m_oplink = new Ui_OPLinkWidget();
m_oplink->setupUi(this);

View File

@ -30,6 +30,7 @@
#include "ui_airframe.h"
#include "configgadgetfactory.h"
#include "uavobjectmanager.h"
#include <extensionsystem/pluginmanager.h>
#include "systemsettings.h"
@ -144,10 +145,9 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi
m_aircraft->aircraftType->addTab(tr("Helicopter"));
m_aircraft->aircraftType->addTab(tr("Ground"));
m_aircraft->aircraftType->addTab(tr("Custom"));
// switchAirframeType(0);
// Connect aircraft type selection dropbox to callback function
connect(m_aircraft->aircraftType, SIGNAL(currentChanged(int)), this, SLOT(switchAirframeType(int)));
connect(m_aircraft->aircraftType, SIGNAL(currentChanged(int)), this, SLOT(frameTypeChanged(int)));
}
/**
@ -158,15 +158,18 @@ ConfigVehicleTypeWidget::~ConfigVehicleTypeWidget()
// Do nothing
}
void ConfigVehicleTypeWidget::switchAirframeType(int index)
void ConfigVehicleTypeWidget::frameTypeChanged(int index)
{
VehicleConfig *vehicleConfig = getVehicleConfigWidget(index);
if (vehicleConfig) {
// switch tab
m_aircraft->airframesWidget->setCurrentWidget(vehicleConfig);
// enable controls
enableControls(isConnected());
// and flag vehicle config as dirty (frame type was changed...)
// flag vehicle config as dirty (frame type was changed...)
setDirty(true);
}
}
@ -175,9 +178,8 @@ void ConfigVehicleTypeWidget::enableControls(bool enable)
{
ConfigTaskWidget::enableControls(enable);
int category = frameCategory(frameType());
VehicleConfig *vehicleConfig = getVehicleConfigWidget(category);
// forward call to selected vehicle config
VehicleConfig *vehicleConfig = (VehicleConfig *)m_aircraft->airframesWidget->currentWidget();
if (vehicleConfig) {
vehicleConfig->enableControls(enable);
@ -193,7 +195,8 @@ void ConfigVehicleTypeWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
Q_UNUSED(obj);
if (!allObjectsUpdated()) {
if (obj) {
// single object was updated, skip...
return;
}
@ -203,7 +206,8 @@ void ConfigVehicleTypeWidget::refreshWidgetsValuesImpl(UAVObject *obj)
m_aircraft->aircraftType->setCurrentIndex(category);
VehicleConfig *vehicleConfig = getVehicleConfigWidget(category);
if (vehicleConfig) {
vehicleConfig->refreshWidgetsValues(ft);
vehicleConfig->setupUI(ft);
vehicleConfig->refreshWidgetsValuesImpl(obj);
}
// update custom tab from others frame settings (to debug/learn hard coded mixers)
@ -211,7 +215,8 @@ void ConfigVehicleTypeWidget::refreshWidgetsValuesImpl(UAVObject *obj)
int customCategory = frameCategory("Custom");
VehicleConfig *vehicleConfig = getVehicleConfigWidget(customCategory);
if (vehicleConfig) {
vehicleConfig->refreshWidgetsValues("Custom");
vehicleConfig->setupUI("Custom");
vehicleConfig->refreshWidgetsValuesImpl(obj);
}
}
@ -229,19 +234,20 @@ void ConfigVehicleTypeWidget::refreshWidgetsValuesImpl(UAVObject *obj)
*/
void ConfigVehicleTypeWidget::updateObjectsFromWidgetsImpl()
{
// Airframe type defaults to Custom
QString ft = "Custom";
VehicleConfig *vehicleConfig = (VehicleConfig *)m_aircraft->airframesWidget->currentWidget();
// frame type defaults to Custom
QString ft = "Custom";
if (vehicleConfig) {
ft = vehicleConfig->updateConfigObjectsFromWidgets();
vehicleConfig->updateObjectsFromWidgetsImpl();
ft = vehicleConfig->getFrameType();
}
// airframe type
// save frame type
setFrameType(ft);
// vehicle name
// save vehicle name
QString name = m_aircraft->nameEdit->text();
setVehicleName(name);
@ -250,7 +256,8 @@ void ConfigVehicleTypeWidget::updateObjectsFromWidgetsImpl()
int customCategory = frameCategory("Custom");
VehicleConfig *vehicleConfig = getVehicleConfigWidget(customCategory);
if (vehicleConfig) {
vehicleConfig->refreshWidgetsValues("Custom");
vehicleConfig->setupUI("Custom");
vehicleConfig->refreshWidgetsValuesImpl(NULL);
}
}
}
@ -355,12 +362,6 @@ VehicleConfig *ConfigVehicleTypeWidget::getVehicleConfigWidget(int frameCategory
if (!m_vehicleIndexMap.contains(frameCategory)) {
// create config widget
vehicleConfig = createVehicleConfigWidget(frameCategory);
if (vehicleConfig) {
// add config widget to UI
int index = m_aircraft->airframesWidget->insertWidget(m_aircraft->airframesWidget->count(), vehicleConfig);
m_vehicleIndexMap[frameCategory] = index;
}
}
int index = m_vehicleIndexMap.value(frameCategory);
vehicleConfig = (VehicleConfig *)m_aircraft->airframesWidget->widget(index);
@ -395,6 +396,10 @@ VehicleConfig *ConfigVehicleTypeWidget::createVehicleConfigWidget(int frameCateg
// bind config widget "field" to this ConfigTaskWidget
// this is necessary to get "dirty" state management
vehicleConfig->registerWidgets(*this);
// add config widget to UI
int index = m_aircraft->airframesWidget->insertWidget(m_aircraft->airframesWidget->count(), vehicleConfig);
m_vehicleIndexMap[frameCategory] = index;
}
return vehicleConfig;
}

View File

@ -73,7 +73,6 @@ private:
// Maps a frame category to its index in the m_aircraft->airframesWidget QStackedWidget
QMap<int, int> m_vehicleIndexMap;
QString frameType();
void setFrameType(QString frameType);
@ -86,7 +85,7 @@ private:
VehicleConfig *createVehicleConfigWidget(int frameCategory);
private slots:
void switchAirframeType(int index);
void frameTypeChanged(int index);
};
#endif // CONFIGVEHICLETYPEWIDGET_H

View File

@ -27,8 +27,12 @@
*/
#include "outputcalibrationpage.h"
#include "ui_outputcalibrationpage.h"
#include "systemalarms.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
const QString OutputCalibrationPage::MULTI_SVG_FILE = QString(":/setupwizard/resources/multirotor-shapes.svg");

View File

@ -49,34 +49,48 @@
#include <QUrl>
#include <QWidget>
ConfigTaskWidget::ConfigTaskWidget(QWidget *parent, bool autopilot) : QWidget(parent),
ConfigTaskWidget::ConfigTaskWidget(QWidget *parent, ConfigTaskType configType) : QWidget(parent),
m_currentBoardId(-1), m_isConnected(false), m_isWidgetUpdatesAllowed(true), m_isDirty(false), m_refreshing(false),
m_wikiURL("Welcome"), m_saveButton(NULL), m_outOfLimitsStyle("background-color: rgb(255, 0, 0);"), m_realtimeUpdateTimer(NULL)
{
m_autopilot = autopilot;
m_configType = configType;
m_pluginManager = ExtensionSystem::PluginManager::instance();
m_objectUtilManager = m_pluginManager->getObject<UAVObjectUtilManager>();
UAVSettingsImportExportFactory *importexportplugin = m_pluginManager->getObject<UAVSettingsImportExportFactory>();
connect(importexportplugin, SIGNAL(importAboutToBegin()), this, SLOT(invalidateObjects()));
m_saveButton = new SmartSaveButton(this);
connect(m_saveButton, SIGNAL(preProcessOperations()), this, SLOT(updateObjectsFromWidgets()));
connect(m_saveButton, SIGNAL(saveSuccessfull()), this, SLOT(clearDirty()));
connect(m_saveButton, SIGNAL(beginOp()), this, SLOT(disableObjectUpdates()));
connect(m_saveButton, SIGNAL(endOp()), this, SLOT(enableObjectUpdates()));
if (m_configType != Child) {
UAVSettingsImportExportFactory *importexportplugin = m_pluginManager->getObject<UAVSettingsImportExportFactory>();
connect(importexportplugin, SIGNAL(importAboutToBegin()), this, SLOT(invalidateObjects()));
if (m_autopilot) {
m_saveButton = new SmartSaveButton(this);
connect(m_saveButton, SIGNAL(preProcessOperations()), this, SLOT(updateObjectsFromWidgets()));
connect(m_saveButton, SIGNAL(saveSuccessfull()), this, SLOT(clearDirty()));
connect(m_saveButton, SIGNAL(beginOp()), this, SLOT(disableObjectUpdates()));
connect(m_saveButton, SIGNAL(endOp()), this, SLOT(enableObjectUpdates()));
}
switch (m_configType) {
case AutoPilot:
{
// connect to telemetry manager
TelemetryManager *tm = m_pluginManager->getObject<TelemetryManager>();
connect(tm, SIGNAL(connected()), this, SLOT(onConnect()));
connect(tm, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
} else {
break;
}
case OPLink:
{
// connect to oplink manager
OPLinkManager *om = m_pluginManager->getObject<OPLinkManager>();
connect(om, SIGNAL(connected()), this, SLOT(onConnect()));
connect(om, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
break;
}
case Child:
default:
// do nothing
break;
}
}
@ -239,6 +253,7 @@ void ConfigTaskWidget::setWidgetBindingObjectEnabled(QString objectName, bool en
Q_ASSERT(object);
bool isRefreshing = m_refreshing;
m_refreshing = true;
foreach(WidgetBinding * binding, m_widgetBindingsPerObject.values(object)) {
@ -252,7 +267,7 @@ void ConfigTaskWidget::setWidgetBindingObjectEnabled(QString objectName, bool en
}
}
m_refreshing = true;
m_refreshing = isRefreshing;
}
bool ConfigTaskWidget::isComboboxOptionSelected(QComboBox *combo, int optionValue)
@ -305,13 +320,25 @@ bool ConfigTaskWidget::isConnected() const
{
bool connected = false;
if (m_autopilot) {
switch (m_configType) {
case AutoPilot:
{
TelemetryManager *tm = m_pluginManager->getObject<TelemetryManager>();
connected = tm->isConnected();
} else {
break;
}
case OPLink:
{
OPLinkManager *om = m_pluginManager->getObject<OPLinkManager>();
connected = om->isConnected();
break;
}
case Child:
default:
// do nothing
break;
}
return connected;
}
@ -328,7 +355,7 @@ void ConfigTaskWidget::bind()
void ConfigTaskWidget::onConnect()
{
if (m_autopilot) {
if (m_configType == AutoPilot) {
m_currentBoardId = m_objectUtilManager->getBoardModel();
}
@ -343,7 +370,7 @@ void ConfigTaskWidget::onConnect()
refreshWidgetsValues();
setDirty(false);
clearDirty();
}
void ConfigTaskWidget::onDisconnect()
@ -365,6 +392,7 @@ void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj)
return;
}
bool isRefreshing = m_refreshing;
m_refreshing = true;
QList<WidgetBinding *> bindings = obj == NULL ? m_widgetBindingsPerObject.values() : m_widgetBindingsPerObject.values(obj);
@ -381,7 +409,7 @@ void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj)
// call specific implementation
refreshWidgetsValuesImpl(obj);
m_refreshing = false;
m_refreshing = isRefreshing;
}
void ConfigTaskWidget::updateObjectsFromWidgets()
@ -407,8 +435,8 @@ void ConfigTaskWidget::helpButtonPressed()
void ConfigTaskWidget::addApplyButton(QPushButton *button)
{
m_saveButton->addApplyButton(button);
button->setVisible(expertMode());
m_saveButton->addApplyButton(button);
}
void ConfigTaskWidget::addSaveButton(QPushButton *button)
@ -444,7 +472,6 @@ bool ConfigTaskWidget::shouldObjectBeSaved(UAVObject *object)
return true;
}
void ConfigTaskWidget::widgetsContentsChanged()
{
QWidget *emitter = ((QWidget *)sender());
@ -501,7 +528,7 @@ void ConfigTaskWidget::widgetsContentsChanged()
void ConfigTaskWidget::clearDirty()
{
setDirty(false);
m_isDirty = false;
}
void ConfigTaskWidget::setDirty(bool value)
@ -514,11 +541,7 @@ void ConfigTaskWidget::setDirty(bool value)
bool ConfigTaskWidget::isDirty()
{
if (m_isConnected) {
return m_isDirty;
} else {
return false;
}
return m_isConnected ? m_isDirty : false;
}
void ConfigTaskWidget::disableObjectUpdates()

View File

@ -100,7 +100,9 @@ class UAVOBJECTWIDGETUTILS_EXPORT ConfigTaskWidget : public QWidget {
Q_OBJECT
public:
ConfigTaskWidget(QWidget *parent = 0, bool autopilot = true);
enum ConfigTaskType { AutoPilot, OPLink, Child };
ConfigTaskWidget(QWidget *parent = 0, ConfigTaskType configType = AutoPilot);
virtual ~ConfigTaskWidget();
void bind();
@ -181,14 +183,12 @@ protected:
virtual void buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits);
virtual void enableControls(bool enable);
void updateEnableControls();
bool isConnected() const;
virtual void refreshWidgetsValuesImpl(UAVObject *) {};
virtual void updateObjectsFromWidgetsImpl() {};
bool isConnected() const;
void updateEnableControls();
protected slots:
void setWidgetBindingObjectEnabled(QString objectName, bool enabled);
@ -233,9 +233,9 @@ private:
bool haslimits;
};
// indicates if this is an "autopilot" widget (CC3D, Revolution, ...) or an OPLink widget
// indicates if this is an "autopilot" widget (CC3D, Revolution, ...), an OPLink widget or a Child widget (for vehicle config)
// TODO the logic that this flag controls should be moved to derived classes
bool m_autopilot;
ConfigTaskType m_configType;
// only valid for "autopilot" widgets
int m_currentBoardId;