diff --git a/ground/openpilotgcs/src/app/app.pro b/ground/openpilotgcs/src/app/app.pro index 4170c0c13..4b1534ad9 100644 --- a/ground/openpilotgcs/src/app/app.pro +++ b/ground/openpilotgcs/src/app/app.pro @@ -4,10 +4,12 @@ include(../shared/qtsingleapplication/qtsingleapplication.pri) TEMPLATE = app TARGET = $$GCS_APP_TARGET DESTDIR = $$GCS_APP_PATH +QT += xml SOURCES += main.cpp include(../rpath.pri) +include(../libs/utils/utils.pri) win32 { CONFIG(debug, debug|release):LIBS *= -lExtensionSystemd -lAggregationd -lQExtSerialPortd diff --git a/ground/openpilotgcs/src/app/main.cpp b/ground/openpilotgcs/src/app/main.cpp index 55f7d5312..29111836c 100644 --- a/ground/openpilotgcs/src/app/main.cpp +++ b/ground/openpilotgcs/src/app/main.cpp @@ -27,6 +27,7 @@ */ #include "qtsingleapplication.h" +#include "utils/xmlconfig.h" #include #include @@ -243,10 +244,10 @@ int main(int argc, char **argv) QString locale = QLocale::system().name(); // Must be done before any QSettings class is created - QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope, + QSettings::setPath(XmlConfig::XmlSettingsFormat, QSettings::SystemScope, QCoreApplication::applicationDirPath()+QLatin1String(SHARE_PATH)); // keep this in sync with the MainWindow ctor in coreplugin/mainwindow.cpp - QSettings settings(QSettings::IniFormat, QSettings::UserScope, + QSettings settings(XmlConfig::XmlSettingsFormat, QSettings::UserScope, QLatin1String("OpenPilot"), QLatin1String("OpenPilotGCS")); overrideSettings(settings, argc, argv); diff --git a/ground/openpilotgcs/src/libs/utils/pathutils.cpp b/ground/openpilotgcs/src/libs/utils/pathutils.cpp index 9b42dfdf5..0ecdd3c85 100644 --- a/ground/openpilotgcs/src/libs/utils/pathutils.cpp +++ b/ground/openpilotgcs/src/libs/utils/pathutils.cpp @@ -26,6 +26,7 @@ */ #include "pathutils.h" +#include "xmlconfig.h" #include #include @@ -97,7 +98,7 @@ QString PathUtils::GetStoragePath() { // This routine works with "/" as the standard: // Work out where the settings are stored on the machine - QSettings set(QSettings::IniFormat, QSettings::UserScope,QLatin1String("OpenPilot"), QLatin1String("OpenPilotGCS")); + QSettings set(XmlConfig::XmlSettingsFormat, QSettings::UserScope,QLatin1String("OpenPilot"), QLatin1String("OpenPilotGCS")); QFileInfo f(set.fileName()); QDir dir(f.absoluteDir()); diff --git a/ground/openpilotgcs/src/libs/utils/utils.pro b/ground/openpilotgcs/src/libs/utils/utils.pro index 570b274f7..7b923a567 100644 --- a/ground/openpilotgcs/src/libs/utils/utils.pro +++ b/ground/openpilotgcs/src/libs/utils/utils.pro @@ -2,7 +2,8 @@ TEMPLATE = lib TARGET = Utils QT += gui \ - network + network \ + xml DEFINES += QTCREATOR_UTILS_LIB @@ -45,6 +46,7 @@ SOURCES += reloadpromptutils.cpp \ pathutils.cpp \ worldmagmodel.cpp \ homelocationutil.cpp +SOURCES += xmlconfig.cpp win32 { SOURCES += abstractprocess_win.cpp \ @@ -95,6 +97,7 @@ HEADERS += utils_global.h \ pathutils.h \ worldmagmodel.h \ homelocationutil.h +HEADERS += xmlconfig.h FORMS += filewizardpage.ui \ projectintropage.ui \ diff --git a/ground/openpilotgcs/src/plugins/importexport/xmlconfig.cpp b/ground/openpilotgcs/src/libs/utils/xmlconfig.cpp similarity index 94% rename from ground/openpilotgcs/src/plugins/importexport/xmlconfig.cpp rename to ground/openpilotgcs/src/libs/utils/xmlconfig.cpp index 79774d696..e924e20bd 100644 --- a/ground/openpilotgcs/src/plugins/importexport/xmlconfig.cpp +++ b/ground/openpilotgcs/src/libs/utils/xmlconfig.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #define NUM_PREFIX "arr_" @@ -84,6 +85,10 @@ void XmlConfig::handleNode(QDomElement* node, QSettings::SettingsMap &map, QStri if ( nodeName.startsWith(NUM_PREFIX) ){ nodeName.replace(NUM_PREFIX, ""); } + // Xml tags are restrictive with allowed characters, + // so we urlencode and replace % with __PCT__ on file + nodeName = nodeName.replace("__PCT__", "%"); + nodeName = QUrl::fromPercentEncoding(nodeName.toAscii()); if ( nodeName == XmlConfig::rootName ) ; @@ -99,7 +104,7 @@ void XmlConfig::handleNode(QDomElement* node, QSettings::SettingsMap &map, QStri handleNode( static_cast(&child), map, path); } else if ( child.isText() ){ - qDebug() << "Key: " << path << " Value:" << node->text(); +// qDebug() << "Key: " << path << " Value:" << node->text(); map.insert(path, stringToVariant(node->text())); } else{ @@ -123,6 +128,10 @@ bool XmlConfig::writeXmlFile(QIODevice &device, const QSettings::SettingsMap &ma if ( elem == "" ){ continue; } + // Xml tags are restrictive with allowed characters, + // so we urlencode and replace % with __PCT__ on file + elem = QString(QUrl::toPercentEncoding(elem)); + elem = elem.replace("%", "__PCT__"); // For arrays, QT will use simple numbers as keys, which is not a valid element in XML. // Therefore we prefixed these. if ( elem.startsWith(NUM_PREFIX) ){ diff --git a/ground/openpilotgcs/src/plugins/importexport/xmlconfig.h b/ground/openpilotgcs/src/libs/utils/xmlconfig.h similarity index 90% rename from ground/openpilotgcs/src/plugins/importexport/xmlconfig.h rename to ground/openpilotgcs/src/libs/utils/xmlconfig.h index 91cba38d1..447b2b6d4 100644 --- a/ground/openpilotgcs/src/plugins/importexport/xmlconfig.h +++ b/ground/openpilotgcs/src/libs/utils/xmlconfig.h @@ -26,13 +26,18 @@ #ifndef XMLCONFIG_H #define XMLCONFIG_H -#include "importexport_global.h" +#if defined(QTCREATOR_UTILS_LIB) +# define XMLCONFIG_EXPORT Q_DECL_EXPORT +#else +# define XMLCONFIG_EXPORT Q_DECL_IMPORT +#endif +#include #include #include #include -class IMPORTEXPORT_EXPORT XmlConfig : QObject +class XMLCONFIG_EXPORT XmlConfig : QObject { public: diff --git a/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp b/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp deleted file mode 100644 index 4528b8580..000000000 --- a/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp +++ /dev/null @@ -1,2169 +0,0 @@ -/** - ****************************************************************************** - * - * @file configairframewidget.cpp - * @author E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ConfigPlugin Config Plugin - * @{ - * @brief Airframe configuration panel - *****************************************************************************/ -/* - * This program 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. - * - * This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include "configairframewidget.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - Helper delegate for the custom mixer editor table. - Taken straight from Qt examples, thanks! - */ -SpinBoxDelegate::SpinBoxDelegate(QObject *parent) - : QItemDelegate(parent) - { - } - -QWidget *SpinBoxDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem &/* option */, - const QModelIndex &/* index */) const -{ - QSpinBox *editor = new QSpinBox(parent); - editor->setMinimum(-127); - editor->setMaximum(127); - - return editor; -} - -void SpinBoxDelegate::setEditorData(QWidget *editor, - const QModelIndex &index) const -{ - int value = index.model()->data(index, Qt::EditRole).toInt(); - - QSpinBox *spinBox = static_cast(editor); - spinBox->setValue(value); -} - -void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const -{ - QSpinBox *spinBox = static_cast(editor); - spinBox->interpretText(); - int value = spinBox->value(); - - model->setData(index, value, Qt::EditRole); -} - -void SpinBoxDelegate::updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, const QModelIndex &/* index */) const -{ - editor->setGeometry(option.rect); -} - -/**********************************************************************************/ - - - -ConfigAirframeWidget::ConfigAirframeWidget(QWidget *parent) : ConfigTaskWidget(parent) -{ - m_aircraft = new Ui_AircraftWidget(); - m_aircraft->setupUi(this); - - ffTuningInProgress = false; - ffTuningPhase = false; - - mixerTypes << "Mixer1Type" << "Mixer2Type" << "Mixer3Type" - << "Mixer4Type" << "Mixer5Type" << "Mixer6Type" << "Mixer7Type" << "Mixer8Type"; - mixerVectors << "Mixer1Vector" << "Mixer2Vector" << "Mixer3Vector" - << "Mixer4Vector" << "Mixer5Vector" << "Mixer6Vector" << "Mixer7Vector" << "Mixer8Vector"; - - QStringList airframeTypes; - airframeTypes << "Fixed Wing" << "Multirotor" << "Helicopter" << "Custom"; - m_aircraft->aircraftType->addItems(airframeTypes); - m_aircraft->aircraftType->setCurrentIndex(1); - - QStringList fixedWingTypes; - fixedWingTypes << "Elevator aileron rudder" << "Elevon" << "Vtail"; - m_aircraft->fixedWingType->addItems(fixedWingTypes); - - QStringList multiRotorTypes; - multiRotorTypes << "Quad +" << "Quad X" << "Hexacopter" << "Octocopter" << "Hexacopter X" << "Octocopter V" << "Octo Coax +" - << "Octo Coax X" << "Hexacopter Y6" << "Tricopter Y"; - m_aircraft->multirotorFrameType->addItems(multiRotorTypes); - - - - QStringList channels; - channels << "None" << "Channel1" << "Channel2" << "Channel3" << - "Channel4" << "Channel5" << "Channel6" << "Channel7" << "Channel8"; - // Now load all the channel assignements for fixed wing - m_aircraft->fwElevator1Channel->addItems(channels); - m_aircraft->fwElevator2Channel->addItems(channels); - m_aircraft->fwEngineChannel->addItems(channels); - m_aircraft->fwRudder1Channel->addItems(channels); - m_aircraft->fwRudder2Channel->addItems(channels); - m_aircraft->fwAileron1Channel->addItems(channels); - m_aircraft->fwAileron2Channel->addItems(channels); - m_aircraft->multiMotor1->addItems(channels); - m_aircraft->multiMotor2->addItems(channels); - m_aircraft->multiMotor3->addItems(channels); - m_aircraft->multiMotor4->addItems(channels); - m_aircraft->multiMotor5->addItems(channels); - m_aircraft->multiMotor6->addItems(channels); - m_aircraft->multiMotor7->addItems(channels); - m_aircraft->multiMotor8->addItems(channels); - m_aircraft->triYawChannel->addItems(channels); - - // Setup the Multirotor picture in the Quad settings interface - m_aircraft->quadShape->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_aircraft->quadShape->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - QSvgRenderer *renderer = new QSvgRenderer(); - renderer->load(QString(":/configgadget/images/quad-shapes.svg")); - quad = new QGraphicsSvgItem(); - quad->setSharedRenderer(renderer); - quad->setElementId("quad-plus"); - QGraphicsScene *scene = new QGraphicsScene(this); - scene->addItem(quad); - scene->setSceneRect(quad->boundingRect()); - m_aircraft->quadShape->setScene(scene); - - // Put combo boxes in line one of the custom mixer table: - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - UAVObjectField* field = obj->getField(QString("Mixer1Type")); - QStringList list = field->getOptions(); - for (int i=0;i<8;i++) { - QComboBox* qb = new QComboBox(m_aircraft->customMixerTable); - qb->addItems(list); - m_aircraft->customMixerTable->setCellWidget(0,i,qb); - } - - SpinBoxDelegate *sbd = new SpinBoxDelegate(); - for (int i=1;i<8; i++) { - m_aircraft->customMixerTable->setItemDelegateForRow(i, sbd); - } - - connect(m_aircraft->saveAircraftToSD, SIGNAL(clicked()), this, SLOT(saveAircraftUpdate())); - connect(m_aircraft->saveAircraftToRAM, SIGNAL(clicked()), this, SLOT(sendAircraftUpdate())); - connect(m_aircraft->getAircraftCurrent, SIGNAL(clicked()), this, SLOT(requestAircraftUpdate())); - connect(m_aircraft->ffSave, SIGNAL(clicked()), this, SLOT(saveAircraftUpdate())); - connect(m_aircraft->ffApply, SIGNAL(clicked()), this, SLOT(sendAircraftUpdate())); - connect(m_aircraft->ffGetCurrent, SIGNAL(clicked()), this, SLOT(requestAircraftUpdate())); - connect(m_aircraft->fixedWingType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString))); - connect(m_aircraft->multirotorFrameType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString))); - connect(m_aircraft->aircraftType, SIGNAL(currentIndexChanged(int)), this, SLOT(switchAirframeType(int))); - requestAircraftUpdate(); - - connect(m_aircraft->fwThrottleReset, SIGNAL(clicked()), this, SLOT(resetFwMixer())); - connect(m_aircraft->mrThrottleCurveReset, SIGNAL(clicked()), this, SLOT(resetMrMixer())); - connect(m_aircraft->customReset1, SIGNAL(clicked()), this, SLOT(resetCt1Mixer())); - connect(m_aircraft->customReset2, SIGNAL(clicked()), this, SLOT(resetCt2Mixer())); - connect(m_aircraft->fixedWingThrottle, SIGNAL(curveUpdated(QList,double)), this, SLOT(updateFwThrottleCurveValue(QList,double))); - connect(m_aircraft->multiThrottleCurve, SIGNAL(curveUpdated(QList,double)), this, SLOT(updateMrThrottleCurveValue(QList,double))); - connect(m_aircraft->customThrottle1Curve, SIGNAL(curveUpdated(QList,double)), this, SLOT(updateCustomThrottle1CurveValue(QList,double))); - connect(m_aircraft->customThrottle2Curve, SIGNAL(curveUpdated(QList,double)), this, SLOT(updateCustomThrottle2CurveValue(QList,double))); - -// connect(m_aircraft->fwAileron1Channel, SIGNAL(currentIndexChanged(int)), this, SLOT(toggleAileron2(int))); -// connect(m_aircraft->fwElevator1Channel, SIGNAL(currentIndexChanged(int)), this, SLOT(toggleElevator2(int))); - - // Now connect the three feed forward test checkboxes - connect(m_aircraft->ffTestBox1, SIGNAL(clicked(bool)), this, SLOT(enableFFTest())); - connect(m_aircraft->ffTestBox2, SIGNAL(clicked(bool)), this, SLOT(enableFFTest())); - connect(m_aircraft->ffTestBox3, SIGNAL(clicked(bool)), this, SLOT(enableFFTest())); - - connect(parent, SIGNAL(autopilotConnected()),this, SLOT(requestAircraftUpdate())); - - // Connect all the help buttons to signal mapper that passes button name to SLOT function - QSignalMapper* signalMapper = new QSignalMapper(this); - connect( m_aircraft->acftTypeHelp, SIGNAL(clicked()), signalMapper, SLOT(map()) ); - signalMapper->setMapping(m_aircraft->acftTypeHelp, m_aircraft->acftTypeHelp->objectName()); - connect( m_aircraft->airplaneTypeHelp, SIGNAL(clicked()), signalMapper, SLOT(map()) ); - signalMapper->setMapping(m_aircraft->airplaneTypeHelp, m_aircraft->airplaneTypeHelp->objectName()); - connect( m_aircraft->channelAssignmentHelp, SIGNAL(clicked()), signalMapper, SLOT(map()) ); - signalMapper->setMapping(m_aircraft->channelAssignmentHelp, m_aircraft->channelAssignmentHelp->objectName()); - connect( m_aircraft->commandHelp, SIGNAL(clicked()), signalMapper, SLOT(map()) ); - signalMapper->setMapping(m_aircraft->commandHelp, QString("commandHelp")); - connect( m_aircraft->throttleCurveHelp, SIGNAL(clicked()), signalMapper, SLOT(map()) ); - signalMapper->setMapping(m_aircraft->throttleCurveHelp, QString("throttleCurveHelp")); - connect( m_aircraft->multiFrameTypeHelp, SIGNAL(clicked()), signalMapper, SLOT(map()) ); - signalMapper->setMapping(m_aircraft->multiFrameTypeHelp, m_aircraft->multiFrameTypeHelp->objectName()); - connect( m_aircraft->throttleCurveHelp_2, SIGNAL(clicked()), signalMapper, SLOT(map()) ); - signalMapper->setMapping(m_aircraft->throttleCurveHelp_2, QString("throttleCurveHelp")); - connect( m_aircraft->tricopterYawHelp, SIGNAL(clicked()), signalMapper, SLOT(map()) ); - signalMapper->setMapping(m_aircraft->tricopterYawHelp, m_aircraft->tricopterYawHelp->objectName()); - connect( m_aircraft->motorOutputChanHelp, SIGNAL(clicked()), signalMapper, SLOT(map()) ); - signalMapper->setMapping(m_aircraft->motorOutputChanHelp, m_aircraft->motorOutputChanHelp->objectName()); - connect( m_aircraft->feedForwardHelp, SIGNAL(clicked()), signalMapper, SLOT(map()) ); - signalMapper->setMapping(m_aircraft->feedForwardHelp, m_aircraft->feedForwardHelp->objectName()); - connect( m_aircraft->commandHelp_2, SIGNAL(clicked()), signalMapper, SLOT(map()) ); - signalMapper->setMapping(m_aircraft->commandHelp_2, QString("commandHelp")); - - connect(signalMapper, SIGNAL(mapped(const QString &)), parent, SLOT(showHelp(const QString &))); -} - -ConfigAirframeWidget::~ConfigAirframeWidget() -{ - // Do nothing -} - -/** - Slot for switching the airframe type. We do it explicitely - rather than a signal in the UI, because we want to force a fitInView of the quad shapes. - This is because this method (fitinview) only works when the widget is shown. - */ -void ConfigAirframeWidget::switchAirframeType(int index){ - m_aircraft->airframesWidget->setCurrentIndex(index); - m_aircraft->quadShape->setSceneRect(quad->boundingRect()); - m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); - if (m_aircraft->aircraftType->findText("Custom")) { - m_aircraft->customMixerTable->resizeColumnsToContents(); - for (int i=0;i<8;i++) { - m_aircraft->customMixerTable->setColumnWidth(i,(m_aircraft->customMixerTable->width()- - m_aircraft->customMixerTable->verticalHeader()->width())/8); - } - } -} - -void ConfigAirframeWidget::showEvent(QShowEvent *event) -{ - Q_UNUSED(event) - // Thit fitInView method should only be called now, once the - // widget is shown, otherwise it cannot compute its values and - // the result is usually a ahrsbargraph that is way too small. - m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); - m_aircraft->customMixerTable->resizeColumnsToContents(); - for (int i=0;i<8;i++) { - m_aircraft->customMixerTable->setColumnWidth(i,(m_aircraft->customMixerTable->width()- - m_aircraft->customMixerTable->verticalHeader()->width())/8); - } -} - -void ConfigAirframeWidget::resizeEvent(QResizeEvent* event) -{ - Q_UNUSED(event); - m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); - // Make the custom table columns autostretch: - m_aircraft->customMixerTable->resizeColumnsToContents(); - for (int i=0;i<8;i++) { - m_aircraft->customMixerTable->setColumnWidth(i,(m_aircraft->customMixerTable->width()- - m_aircraft->customMixerTable->verticalHeader()->width())/8); - } - -} - - -void ConfigAirframeWidget::toggleAileron2(int index) -{ - if (index) { - m_aircraft->fwAileron2Channel->setEnabled(true); - m_aircraft->fwAileron2Label->setEnabled(true); - } else { - m_aircraft->fwAileron2Channel->setEnabled(false); - m_aircraft->fwAileron2Label->setEnabled(false); - } -} - -void ConfigAirframeWidget::toggleElevator2(int index) -{ - if (index) { - m_aircraft->fwElevator2Channel->setEnabled(true); - m_aircraft->fwElevator2Label->setEnabled(true); - } else { - m_aircraft->fwElevator2Channel->setEnabled(false); - m_aircraft->fwElevator2Label->setEnabled(false); - } -} - -void ConfigAirframeWidget::toggleRudder2(int index) -{ - if (index) { - m_aircraft->fwRudder2Channel->setEnabled(true); - m_aircraft->fwRudder2Label->setEnabled(true); - } else { - m_aircraft->fwRudder2Channel->setEnabled(false); - m_aircraft->fwRudder2Label->setEnabled(false); - } -} - -///////////////////////////////////////////////////////// -/// Feed Forward Testing -///////////////////////////////////////////////////////// - -/** - Enables and runs feed forward testing - */ -void ConfigAirframeWidget::enableFFTest() -{ - // Role: - // - Check if all three checkboxes are checked - // - Every other timer event: toggle engine from 45% to 55% - // - Every other time event: send FF settings to flight FW - if (m_aircraft->ffTestBox1->isChecked() && - m_aircraft->ffTestBox2->isChecked() && - m_aircraft->ffTestBox3->isChecked()) { - if (!ffTuningInProgress) - { - // Initiate tuning: - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ManualControlCommand"))); - UAVObject::Metadata mdata = obj->getMetadata(); - accInitialData = mdata; - mdata.flightAccess = UAVObject::ACCESS_READONLY; - obj->setMetadata(mdata); - } - // Depending on phase, either move actuator or send FF settings: - if (ffTuningPhase) { - // Send FF settings to the board - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - UAVObjectField* field = obj->getField(QString("FeedForward")); - field->setDouble((double)m_aircraft->feedForwardSlider->value()/100); - field = obj->getField(QString("AccelTime")); - field->setDouble(m_aircraft->accelTime->value()); - field = obj->getField(QString("DecelTime")); - field->setDouble(m_aircraft->decelTime->value()); - field = obj->getField(QString("MaxAccel")); - field->setDouble(m_aircraft->maxAccelSlider->value()); - obj->updated(); - } else { - // Toggle motor state - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ManualControlCommand"))); - double value = obj->getField("Throttle")->getDouble(); - double target = (value < 0.5) ? 0.55 : 0.45; - obj->getField("Throttle")->setValue(target); - obj->updated(); - } - ffTuningPhase = !ffTuningPhase; - ffTuningInProgress = true; - QTimer::singleShot(1000, this, SLOT(enableFFTest())); - } else { - // - If no: disarm timer, restore actuatorcommand metadata - // Disarm! - if (ffTuningInProgress) { - ffTuningInProgress = false; - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ManualControlCommand"))); - UAVObject::Metadata mdata = obj->getMetadata(); - mdata = accInitialData; // Restore metadata - obj->setMetadata(mdata); - } - } -} - - -/** - Resets Fixed wing throttle mixer - */ -void ConfigAirframeWidget::resetFwMixer() -{ - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - UAVObjectField* field = obj->getField(QString("ThrottleCurve1")); - resetMixer(m_aircraft->fixedWingThrottle, field->getNumElements()); -} - -/** - Resets Multirotor throttle mixer - */ -void ConfigAirframeWidget::resetMrMixer() -{ - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - UAVObjectField* field = obj->getField(QString("ThrottleCurve1")); - resetMixer(m_aircraft->multiThrottleCurve, field->getNumElements()); -} - -/** - Resets Custom throttle 1 mixer - */ -void ConfigAirframeWidget::resetCt1Mixer() -{ - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - UAVObjectField* field = obj->getField(QString("ThrottleCurve1")); - resetMixer(m_aircraft->customThrottle1Curve, field->getNumElements()); -} - -/** - Resets Custom throttle 2 mixer - */ -void ConfigAirframeWidget::resetCt2Mixer() -{ - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - UAVObjectField* field = obj->getField(QString("ThrottleCurve2")); - resetMixer(m_aircraft->customThrottle2Curve, field->getNumElements()); -} - - -/** - Resets a mixer curve - */ -void ConfigAirframeWidget::resetMixer(MixerCurveWidget *mixer, int numElements) -{ - QList curveValues; - for (double i=0; iinitCurve(curveValues); -} - -/** - Updates the currently moved throttle curve item value - */ -void ConfigAirframeWidget::updateFwThrottleCurveValue(QList list, double value) -{ - Q_UNUSED(list); - m_aircraft->fwThrottleCurveItemValue->setText(QString().sprintf("Val: %.2f",value)); -} - -/** - Updates the currently moved throttle curve item value - */ -void ConfigAirframeWidget::updateMrThrottleCurveValue(QList list, double value) -{ - Q_UNUSED(list); - m_aircraft->mrThrottleCurveItemValue->setText(QString().sprintf("Val: %.2f",value)); -} - -/** - Updates the currently moved throttle curve item value (Custom throttle 1) - */ -void ConfigAirframeWidget::updateCustomThrottle1CurveValue(QList list, double value) -{ - Q_UNUSED(list); - m_aircraft->customThrottleCurve1Value->setText(QString().sprintf("Val: %.2f",value)); -} - -/** - Updates the currently moved throttle curve item value (Custom throttle 2) - */ -void ConfigAirframeWidget::updateCustomThrottle2CurveValue(QList list, double value) -{ - Q_UNUSED(list); - m_aircraft->customThrottleCurve2Value->setText(QString().sprintf("Val: %.2f",value)); -} - - -/************************** - * Aircraft settings - **************************/ -/** - Request the current value of the SystemSettings which holds the aircraft type - */ -void ConfigAirframeWidget::requestAircraftUpdate() -{ - // Get the Airframe type from the system settings: - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings"))); - Q_ASSERT(obj); - obj->requestUpdate(); - UAVObjectField *field = obj->getField(QString("AirframeType")); - Q_ASSERT(field); - // At this stage, we will need to have some hardcoded settings in this code, this - // is not ideal, but here you go. - QString frameType = field->getValue().toString(); - setupAirframeUI(frameType); - - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - obj->requestUpdate(); - field = obj->getField(QString("ThrottleCurve1")); - Q_ASSERT(field); - QList curveValues; - // If the 1st element of the curve is <= -10, then the curve - // is a straight line (that's how the mixer works on the mainboard): - if (field->getValue(0).toInt() <= -10) { - for (double i=0; igetNumElements(); i++) { - curveValues.append(i/(field->getNumElements()-1)); - } - } else { - for (unsigned int i=0; i < field->getNumElements(); i++) { - curveValues.append(field->getValue(i).toDouble()); - } - } - // Setup all Throttle1 curves for all types of airframes - m_aircraft->fixedWingThrottle->initCurve(curveValues); - m_aircraft->multiThrottleCurve->initCurve(curveValues); - - // Load the Settings for fixed wing frames: - if (frameType.startsWith("FixedWing")) { - // Then retrieve how channels are setup - obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorSettings"))); - Q_ASSERT(obj); - field = obj->getField(QString("FixedWingThrottle")); - Q_ASSERT(field); - m_aircraft->fwEngineChannel->setCurrentIndex(m_aircraft->fwEngineChannel->findText(field->getValue().toString())); - field = obj->getField(QString("FixedWingRoll1")); - Q_ASSERT(field); - m_aircraft->fwAileron1Channel->setCurrentIndex(m_aircraft->fwAileron1Channel->findText(field->getValue().toString())); - field = obj->getField(QString("FixedWingRoll2")); - Q_ASSERT(field); - m_aircraft->fwAileron2Channel->setCurrentIndex(m_aircraft->fwAileron2Channel->findText(field->getValue().toString())); - field = obj->getField(QString("FixedWingPitch1")); - Q_ASSERT(field); - m_aircraft->fwElevator1Channel->setCurrentIndex(m_aircraft->fwElevator1Channel->findText(field->getValue().toString())); - field = obj->getField(QString("FixedWingPitch2")); - Q_ASSERT(field); - m_aircraft->fwElevator2Channel->setCurrentIndex(m_aircraft->fwElevator2Channel->findText(field->getValue().toString())); - field = obj->getField(QString("FixedWingYaw1")); - Q_ASSERT(field); - m_aircraft->fwRudder1Channel->setCurrentIndex(m_aircraft->fwRudder1Channel->findText(field->getValue().toString())); - field = obj->getField(QString("FixedWingYaw2")); - Q_ASSERT(field); - m_aircraft->fwRudder2Channel->setCurrentIndex(m_aircraft->fwRudder2Channel->findText(field->getValue().toString())); - - if (frameType == "FixedWingElevon") { - // If the airframe is elevon, restore the slider setting - // Find the channel number for Elevon1 (FixedWingRoll1) - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - int chMixerNumber = m_aircraft->fwAileron1Channel->currentIndex()-1; - if (chMixerNumber >= 0) { // If for some reason the actuators were incoherent, we might fail here, hence the check. - field = obj->getField(mixerVectors.at(chMixerNumber)); - int ti = field->getElementNames().indexOf("Roll"); - m_aircraft->elevonSlider1->setValue(field->getDouble(ti)*100); - ti = field->getElementNames().indexOf("Pitch"); - m_aircraft->elevonSlider2->setValue(field->getDouble(ti)*100); - } - } - if (frameType == "FixedWingVtail") { - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - int chMixerNumber = m_aircraft->fwElevator1Channel->currentIndex()-1; - if (chMixerNumber >=0) { - field = obj->getField(mixerVectors.at(chMixerNumber)); - int ti = field->getElementNames().indexOf("Yaw"); - m_aircraft->elevonSlider1->setValue(field->getDouble(ti)*100); - ti = field->getElementNames().indexOf("Pitch"); - m_aircraft->elevonSlider2->setValue(field->getDouble(ti)*100); - } - } - - } else if (frameType == "QuadX" || frameType == "QuadP" || - frameType == "Hexa" || frameType == "Octo" || - frameType == "HexaCoax" || frameType == "OctoV" || - frameType == "HexaX" || frameType == "OctoCoaxP" || - frameType == "OctoCoaxX" || frameType == "Tri") { - ////////////////////////////////////////////////////////////////// - // Retrieve Multirotor settings - ////////////////////////////////////////////////////////////////// - - obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorSettings"))); - Q_ASSERT(obj); - if (frameType == "QuadP") { - // Motors 1/2/3/4 are: N / E / S / W - field = obj->getField(QString("VTOLMotorN")); - Q_ASSERT(field); - m_aircraft->multiMotor1->setCurrentIndex(m_aircraft->multiMotor1->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorE")); - Q_ASSERT(field); - m_aircraft->multiMotor2->setCurrentIndex(m_aircraft->multiMotor2->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorS")); - Q_ASSERT(field); - m_aircraft->multiMotor3->setCurrentIndex(m_aircraft->multiMotor3->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorW")); - Q_ASSERT(field); - m_aircraft->multiMotor4->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - int eng= m_aircraft->multiMotor1->currentIndex()-1; - // eng will be -1 if value is set to "None" - if (eng > -1) { - field = obj->getField(mixerVectors.at(eng)); - int i = field->getElementNames().indexOf("Pitch"); - double val = field->getDouble(i)/1.27; - m_aircraft->mrPitchMixLevel->setValue(val); - i = field->getElementNames().indexOf("Yaw"); - val = (1-field->getDouble(i)/1.27); - m_aircraft->mrYawMixLevel->setValue(val); - eng = m_aircraft->multiMotor2->currentIndex()-1; - field = obj->getField(mixerVectors.at(eng)); - i = field->getElementNames().indexOf("Roll"); - val = -field->getDouble(i)/1.27; - m_aircraft->mrRollMixLevel->setValue(val); - } - } else if (frameType == "QuadX") { - // Motors 1/2/3/4 are: NW / NE / SE / SW - field = obj->getField(QString("VTOLMotorNW")); - Q_ASSERT(field); - m_aircraft->multiMotor1->setCurrentIndex(m_aircraft->multiMotor1->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorNE")); - Q_ASSERT(field); - m_aircraft->multiMotor2->setCurrentIndex(m_aircraft->multiMotor2->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorSE")); - Q_ASSERT(field); - m_aircraft->multiMotor3->setCurrentIndex(m_aircraft->multiMotor3->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorSW")); - Q_ASSERT(field); - m_aircraft->multiMotor4->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - int eng= m_aircraft->multiMotor1->currentIndex()-1; - // eng will be -1 if value is set to "None" - if (eng > -1) { - field = obj->getField(mixerVectors.at(eng)); - int i = field->getElementNames().indexOf("Pitch"); - double val = field->getDouble(i)/1.27; - m_aircraft->mrPitchMixLevel->setValue(val); - i = field->getElementNames().indexOf("Yaw"); - val = 1-field->getDouble(i)/1.27; - m_aircraft->mrYawMixLevel->setValue(val); - i = field->getElementNames().indexOf("Roll"); - val = field->getDouble(i)/1.27; - m_aircraft->mrRollMixLevel->setValue(val); - } - } else if (frameType == "Hexa") { - // Motors 1/2/3 4/5/6 are: N / NE / SE / S / SW / NW - field = obj->getField(QString("VTOLMotorN")); - m_aircraft->multiMotor1->setCurrentIndex(m_aircraft->multiMotor1->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorNE")); - m_aircraft->multiMotor2->setCurrentIndex(m_aircraft->multiMotor2->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorSE")); - m_aircraft->multiMotor3->setCurrentIndex(m_aircraft->multiMotor3->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorS")); - m_aircraft->multiMotor4->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorSW")); - m_aircraft->multiMotor5->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorNW")); - m_aircraft->multiMotor6->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - int eng= m_aircraft->multiMotor1->currentIndex()-1; - // eng will be -1 if value is set to "None" - if (eng > -1) { - field = obj->getField(mixerVectors.at(eng)); - int i = field->getElementNames().indexOf("Pitch"); - double val = floor(field->getDouble(i)/1.27); - m_aircraft->mrPitchMixLevel->setValue(val); - i = field->getElementNames().indexOf("Yaw"); - val = floor(-field->getDouble(i)/1.27); - m_aircraft->mrYawMixLevel->setValue(val); - eng = m_aircraft->multiMotor2->currentIndex()-1; - field = obj->getField(mixerVectors.at(eng)); - i = field->getElementNames().indexOf("Roll"); - val = floor(1-field->getDouble(i)/1.27); - m_aircraft->mrRollMixLevel->setValue(val); - } - } else if (frameType == "HexaX") { - // Motors 1/2/3 4/5/6 are: NE / E / SE / SW / W / NW - field = obj->getField(QString("VTOLMotorNE")); - m_aircraft->multiMotor1->setCurrentIndex(m_aircraft->multiMotor1->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorE")); - m_aircraft->multiMotor2->setCurrentIndex(m_aircraft->multiMotor2->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorSE")); - m_aircraft->multiMotor3->setCurrentIndex(m_aircraft->multiMotor3->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorSW")); - m_aircraft->multiMotor4->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorW")); - m_aircraft->multiMotor5->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorNW")); - m_aircraft->multiMotor6->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - int eng= m_aircraft->multiMotor1->currentIndex()-1; - // eng will be -1 if value is set to "None" - if (eng > -1) { - field = obj->getField(mixerVectors.at(eng)); - int i = field->getElementNames().indexOf("Pitch"); - double val = floor(field->getDouble(i)/1.27); - m_aircraft->mrPitchMixLevel->setValue(val); - i = field->getElementNames().indexOf("Yaw"); - val = floor(-field->getDouble(i)/1.27); - m_aircraft->mrYawMixLevel->setValue(val); - eng = m_aircraft->multiMotor2->currentIndex()-1; - field = obj->getField(mixerVectors.at(eng)); - i = field->getElementNames().indexOf("Roll"); - val = floor(1-field->getDouble(i)/1.27); - m_aircraft->mrRollMixLevel->setValue(val); - } - } else if (frameType == "HexaCoax") { - // Motors 1/2/3 4/5/6 are: NW/W NE/E S/SE - field = obj->getField(QString("VTOLMotorNW")); - m_aircraft->multiMotor1->setCurrentIndex(m_aircraft->multiMotor1->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorW")); - m_aircraft->multiMotor2->setCurrentIndex(m_aircraft->multiMotor2->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorNE")); - m_aircraft->multiMotor3->setCurrentIndex(m_aircraft->multiMotor3->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorE")); - m_aircraft->multiMotor4->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorS")); - m_aircraft->multiMotor5->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorSE")); - m_aircraft->multiMotor6->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - int eng= m_aircraft->multiMotor1->currentIndex()-1; - // eng will be -1 if value is set to "None" - if (eng > -1) { - field = obj->getField(mixerVectors.at(eng)); - int i = field->getElementNames().indexOf("Pitch"); - double val = floor(2*field->getDouble(i)/1.27); - m_aircraft->mrPitchMixLevel->setValue(val); - i = field->getElementNames().indexOf("Yaw"); - val = floor(-field->getDouble(i)/1.27); - m_aircraft->mrYawMixLevel->setValue(val); - i = field->getElementNames().indexOf("Roll"); - val = floor(field->getDouble(i)/1.27); - m_aircraft->mrRollMixLevel->setValue(val); - } - } else if (frameType == "Octo" || frameType == "OctoV" || - frameType == "OctoCoaxP") { - // Motors 1 to 8 are N / NE / E / etc - field = obj->getField(QString("VTOLMotorN")); - Q_ASSERT(field); - m_aircraft->multiMotor1->setCurrentIndex(m_aircraft->multiMotor1->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorNE")); - Q_ASSERT(field); - m_aircraft->multiMotor2->setCurrentIndex(m_aircraft->multiMotor2->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorE")); - Q_ASSERT(field); - m_aircraft->multiMotor3->setCurrentIndex(m_aircraft->multiMotor3->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorSE")); - Q_ASSERT(field); - m_aircraft->multiMotor4->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorS")); - Q_ASSERT(field); - m_aircraft->multiMotor5->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorSW")); - Q_ASSERT(field); - m_aircraft->multiMotor6->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorW")); - Q_ASSERT(field); - m_aircraft->multiMotor7->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorNW")); - Q_ASSERT(field); - m_aircraft->multiMotor8->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - int eng= m_aircraft->multiMotor1->currentIndex()-1; - // eng will be -1 if value is set to "None" - if (eng > -1) { - if (frameType == "Octo") { - field = obj->getField(mixerVectors.at(eng)); - int i = field->getElementNames().indexOf("Pitch"); - double val = floor(field->getDouble(i)/1.27); - m_aircraft->mrPitchMixLevel->setValue(val); - i = field->getElementNames().indexOf("Yaw"); - val = floor(-field->getDouble(i)/1.27); - m_aircraft->mrYawMixLevel->setValue(val); - eng = m_aircraft->multiMotor2->currentIndex()-1; - field = obj->getField(mixerVectors.at(eng)); - i = field->getElementNames().indexOf("Roll"); - val = floor(-field->getDouble(i)/1.27); - m_aircraft->mrRollMixLevel->setValue(val); - } else if (frameType == "OctoV") { - field = obj->getField(mixerVectors.at(eng)); - int i = field->getElementNames().indexOf("Yaw"); - double val = floor(-field->getDouble(i)/1.27); - m_aircraft->mrYawMixLevel->setValue(val); - i = field->getElementNames().indexOf("Roll"); - val = floor(-field->getDouble(i)/1.27); - m_aircraft->mrRollMixLevel->setValue(val); - eng = m_aircraft->multiMotor2->currentIndex()-1; - field = obj->getField(mixerVectors.at(eng)); - i = field->getElementNames().indexOf("Pitch"); - val = floor(field->getDouble(i)/1.27); - m_aircraft->mrPitchMixLevel->setValue(val); - - } else if (frameType == "OctoCoaxP") { - field = obj->getField(mixerVectors.at(eng)); - int i = field->getElementNames().indexOf("Pitch"); - double val = floor(field->getDouble(i)/1.27); - m_aircraft->mrPitchMixLevel->setValue(val); - i = field->getElementNames().indexOf("Yaw"); - val = floor(-field->getDouble(i)/1.27); - m_aircraft->mrYawMixLevel->setValue(val); - eng = m_aircraft->multiMotor3->currentIndex()-1; - field = obj->getField(mixerVectors.at(eng)); - i = field->getElementNames().indexOf("Roll"); - val = floor(-field->getDouble(i)/1.27); - m_aircraft->mrRollMixLevel->setValue(val); - - } - } - } else if (frameType == "OctoCoaxX") { - // Motors 1 to 8 are N / NE / E / etc - field = obj->getField(QString("VTOLMotorNW")); - Q_ASSERT(field); - m_aircraft->multiMotor1->setCurrentIndex(m_aircraft->multiMotor1->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorN")); - Q_ASSERT(field); - m_aircraft->multiMotor2->setCurrentIndex(m_aircraft->multiMotor2->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorNE")); - Q_ASSERT(field); - m_aircraft->multiMotor3->setCurrentIndex(m_aircraft->multiMotor3->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorE")); - Q_ASSERT(field); - m_aircraft->multiMotor4->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorSE")); - Q_ASSERT(field); - m_aircraft->multiMotor5->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorS")); - Q_ASSERT(field); - m_aircraft->multiMotor6->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorSW")); - Q_ASSERT(field); - m_aircraft->multiMotor7->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorW")); - Q_ASSERT(field); - m_aircraft->multiMotor8->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString())); - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - int eng= m_aircraft->multiMotor1->currentIndex()-1; - // eng will be -1 if value is set to "None" - if (eng > -1) { - field = obj->getField(mixerVectors.at(eng)); - int i = field->getElementNames().indexOf("Pitch"); - double val = floor(field->getDouble(i)/1.27); - m_aircraft->mrPitchMixLevel->setValue(val); - i = field->getElementNames().indexOf("Yaw"); - val = floor(-field->getDouble(i)/1.27); - m_aircraft->mrYawMixLevel->setValue(val); - i = field->getElementNames().indexOf("Roll"); - val = floor(field->getDouble(i)/1.27); - m_aircraft->mrRollMixLevel->setValue(val); - } - } else if (frameType == "Tri") { - // Motors 1 to 8 are N / NE / E / etc - field = obj->getField(QString("VTOLMotorNW")); - Q_ASSERT(field); - m_aircraft->multiMotor1->setCurrentIndex(m_aircraft->multiMotor1->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorNE")); - Q_ASSERT(field); - m_aircraft->multiMotor2->setCurrentIndex(m_aircraft->multiMotor2->findText(field->getValue().toString())); - field = obj->getField(QString("VTOLMotorS")); - Q_ASSERT(field); - m_aircraft->multiMotor3->setCurrentIndex(m_aircraft->multiMotor3->findText(field->getValue().toString())); - field = obj->getField(QString("FixedWingYaw1")); - Q_ASSERT(field); - m_aircraft->triYawChannel->setCurrentIndex(m_aircraft->multiMotor3->findText(field->getValue().toString())); - - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - int eng= m_aircraft->multiMotor1->currentIndex()-1; - // eng will be -1 if value is set to "None" - if (eng > -1) { - field = obj->getField(mixerVectors.at(eng)); - int i = field->getElementNames().indexOf("Pitch"); - double val = floor(2*field->getDouble(i)/1.27); - m_aircraft->mrPitchMixLevel->setValue(val); - i = field->getElementNames().indexOf("Roll"); - val = floor(field->getDouble(i)/1.27); - m_aircraft->mrRollMixLevel->setValue(val); - } - - } - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - // Now, retrieve the Feedforward values: - field = obj->getField(QString("FeedForward")); - Q_ASSERT(field); - m_aircraft->feedForwardSlider->setValue(field->getDouble()*100); - field = obj->getField(QString("AccelTime")); - Q_ASSERT(field); - m_aircraft->accelTime->setValue(field->getDouble()); - field = obj->getField(QString("DecelTime")); - Q_ASSERT(field); - m_aircraft->decelTime->setValue(field->getDouble()); - field = obj->getField(QString("MaxAccel")); - Q_ASSERT(field); - m_aircraft->maxAccelSlider->setValue(field->getDouble()); - - } else if (frameType == "HeliCP") { - m_aircraft->widget_3->requestccpmUpdate(); - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Helicopter"));//"Helicopter" - } else if (frameType == "Custom") { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Custom")); - } - - updateCustomAirframeUI(); -} - -/** - \brief Sets up the mixer depending on Airframe type. Accepts either system settings or - combo box entry from airframe type, as those do not overlap. - */ -void ConfigAirframeWidget::setupAirframeUI(QString frameType) -{ - if (frameType == "FixedWing" || frameType == "Elevator aileron rudder") { - // Setup the UI - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Fixed Wing")); - m_aircraft->fixedWingType->setCurrentIndex(m_aircraft->fixedWingType->findText("Elevator aileron rudder")); - m_aircraft->fwRudder1Channel->setEnabled(true); - m_aircraft->fwRudder1Label->setEnabled(true); - m_aircraft->fwRudder2Channel->setEnabled(true); - m_aircraft->fwRudder2Label->setEnabled(true); - m_aircraft->fwElevator1Channel->setEnabled(true); - m_aircraft->fwElevator1Label->setEnabled(true); - m_aircraft->fwElevator2Channel->setEnabled(true); - m_aircraft->fwElevator2Label->setEnabled(true); - m_aircraft->fwAileron1Channel->setEnabled(true); - m_aircraft->fwAileron1Label->setEnabled(true); - m_aircraft->fwAileron2Channel->setEnabled(true); - m_aircraft->fwAileron2Label->setEnabled(true); - - m_aircraft->fwAileron1Label->setText("Aileron 1"); - m_aircraft->fwAileron2Label->setText("Aileron 2"); - m_aircraft->fwElevator1Label->setText("Elevator 1"); - m_aircraft->fwElevator2Label->setText("Elevator 2"); - m_aircraft->elevonMixBox->setHidden(true); - - } else if (frameType == "FixedWingElevon" || frameType == "Elevon") { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Fixed Wing")); - m_aircraft->fixedWingType->setCurrentIndex(m_aircraft->fixedWingType->findText("Elevon")); - m_aircraft->fwAileron1Label->setText("Elevon 1"); - m_aircraft->fwAileron2Label->setText("Elevon 2"); - m_aircraft->fwElevator1Channel->setEnabled(false); - m_aircraft->fwElevator1Label->setEnabled(false); - m_aircraft->fwElevator2Channel->setEnabled(false); - m_aircraft->fwElevator2Label->setEnabled(false); - m_aircraft->fwRudder1Channel->setEnabled(true); - m_aircraft->fwRudder1Label->setEnabled(true); - m_aircraft->fwRudder2Channel->setEnabled(true); - m_aircraft->fwRudder2Label->setEnabled(true); - m_aircraft->fwElevator1Label->setText("Elevator 1"); - m_aircraft->fwElevator2Label->setText("Elevator 2"); - m_aircraft->elevonMixBox->setHidden(false); - m_aircraft->elevonLabel1->setText("Roll"); - m_aircraft->elevonLabel2->setText("Pitch"); - - } else if (frameType == "FixedWingVtail" || frameType == "Vtail") { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Fixed Wing")); - m_aircraft->fixedWingType->setCurrentIndex(m_aircraft->fixedWingType->findText("Vtail")); - m_aircraft->fwRudder1Channel->setEnabled(false); - m_aircraft->fwRudder1Label->setEnabled(false); - m_aircraft->fwRudder2Channel->setEnabled(false); - m_aircraft->fwRudder2Label->setEnabled(false); - m_aircraft->fwElevator1Channel->setEnabled(true); - m_aircraft->fwElevator1Label->setEnabled(true); - m_aircraft->fwElevator1Label->setText("Vtail 1"); - m_aircraft->fwElevator2Label->setText("Vtail 2"); - m_aircraft->elevonMixBox->setHidden(false); - m_aircraft->fwElevator2Channel->setEnabled(true); - m_aircraft->fwElevator2Label->setEnabled(true); - m_aircraft->fwAileron1Label->setText("Aileron 1"); - m_aircraft->fwAileron2Label->setText("Aileron 2"); - m_aircraft->elevonLabel1->setText("Rudder"); - m_aircraft->elevonLabel2->setText("Pitch"); - - } else if (frameType == "QuadX" || frameType == "Quad X") { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); - m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Quad X")); - quad->setElementId("quad-X"); - m_aircraft->multiMotor4->setEnabled(true); - m_aircraft->multiMotor5->setEnabled(false); - m_aircraft->multiMotor6->setEnabled(false); - m_aircraft->multiMotor7->setEnabled(false); - m_aircraft->multiMotor8->setEnabled(false); - m_aircraft->triYawChannel->setEnabled(false); - m_aircraft->mrRollMixLevel->setValue(50); - m_aircraft->mrPitchMixLevel->setValue(50); - m_aircraft->mrYawMixLevel->setValue(50); - } else if (frameType == "QuadP" || frameType == "Quad +") { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); - m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Quad +")); - quad->setElementId("quad-plus"); - m_aircraft->multiMotor4->setEnabled(true); - m_aircraft->multiMotor5->setEnabled(false); - m_aircraft->multiMotor6->setEnabled(false); - m_aircraft->multiMotor7->setEnabled(false); - m_aircraft->multiMotor8->setEnabled(false); - m_aircraft->triYawChannel->setEnabled(false); - m_aircraft->mrRollMixLevel->setValue(100); - m_aircraft->mrPitchMixLevel->setValue(100); - m_aircraft->mrYawMixLevel->setValue(50); - } else if (frameType == "Hexa" || frameType == "Hexacopter") { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); - m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Hexacopter")); - quad->setElementId("quad-hexa"); - m_aircraft->multiMotor4->setEnabled(true); - m_aircraft->multiMotor5->setEnabled(true); - m_aircraft->multiMotor6->setEnabled(true); - m_aircraft->multiMotor7->setEnabled(false); - m_aircraft->multiMotor8->setEnabled(false); - m_aircraft->triYawChannel->setEnabled(false); - m_aircraft->mrRollMixLevel->setValue(50); - m_aircraft->mrPitchMixLevel->setValue(33); - m_aircraft->mrYawMixLevel->setValue(33); - } else if (frameType == "Octo" || frameType == "Octocopter") { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); - m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Octocopter")); - quad->setElementId("quad-octo"); - m_aircraft->multiMotor4->setEnabled(true); - m_aircraft->multiMotor5->setEnabled(true); - m_aircraft->multiMotor6->setEnabled(true); - m_aircraft->multiMotor7->setEnabled(true); - m_aircraft->multiMotor8->setEnabled(true); - m_aircraft->triYawChannel->setEnabled(false); - m_aircraft->mrRollMixLevel->setValue(33); - m_aircraft->mrPitchMixLevel->setValue(33); - m_aircraft->mrYawMixLevel->setValue(25); - } else if (frameType == "HexaX" || frameType == "Hexacopter X" ) { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); - m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Hexacopter X")); - quad->setElementId("quad-hexa-H"); - m_aircraft->multiMotor4->setEnabled(true); - m_aircraft->multiMotor5->setEnabled(true); - m_aircraft->multiMotor6->setEnabled(true); - m_aircraft->multiMotor7->setEnabled(false); - m_aircraft->multiMotor8->setEnabled(false); - m_aircraft->triYawChannel->setEnabled(false); - m_aircraft->mrRollMixLevel->setValue(33); - m_aircraft->mrPitchMixLevel->setValue(50); - m_aircraft->mrYawMixLevel->setValue(33); - - } else if (frameType == "OctoV" || frameType == "Octocopter V") { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); - m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Octocopter V")); - quad->setElementId("quad-octo-v"); - m_aircraft->multiMotor4->setEnabled(true); - m_aircraft->multiMotor5->setEnabled(true); - m_aircraft->multiMotor6->setEnabled(true); - m_aircraft->multiMotor7->setEnabled(true); - m_aircraft->multiMotor8->setEnabled(true); - m_aircraft->triYawChannel->setEnabled(false); - m_aircraft->mrRollMixLevel->setValue(25); - m_aircraft->mrPitchMixLevel->setValue(25); - m_aircraft->mrYawMixLevel->setValue(25); - - } else if (frameType == "OctoCoaxP" || frameType == "Octo Coax +") { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); - m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Octo Coax +")); - quad->setElementId("octo-coax-P"); - m_aircraft->multiMotor4->setEnabled(true); - m_aircraft->multiMotor5->setEnabled(true); - m_aircraft->multiMotor6->setEnabled(true); - m_aircraft->multiMotor7->setEnabled(true); - m_aircraft->multiMotor8->setEnabled(true); - m_aircraft->triYawChannel->setEnabled(false); - m_aircraft->mrRollMixLevel->setValue(100); - m_aircraft->mrPitchMixLevel->setValue(100); - m_aircraft->mrYawMixLevel->setValue(50); - - } else if (frameType == "OctoCoaxX" || frameType == "Octo Coax X") { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); - m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Octo Coax X")); - quad->setElementId("octo-coax-X"); - m_aircraft->multiMotor4->setEnabled(true); - m_aircraft->multiMotor5->setEnabled(true); - m_aircraft->multiMotor6->setEnabled(true); - m_aircraft->multiMotor7->setEnabled(true); - m_aircraft->multiMotor8->setEnabled(true); - m_aircraft->triYawChannel->setEnabled(false); - m_aircraft->mrRollMixLevel->setValue(50); - m_aircraft->mrPitchMixLevel->setValue(50); - m_aircraft->mrYawMixLevel->setValue(50); - - } else if (frameType == "HexaCoax" || frameType == "Hexacopter Y6") { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); - m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Hexacopter Y6")); - quad->setElementId("hexa-coax"); - m_aircraft->multiMotor4->setEnabled(true); - m_aircraft->multiMotor5->setEnabled(true); - m_aircraft->multiMotor6->setEnabled(true); - m_aircraft->multiMotor7->setEnabled(false); - m_aircraft->multiMotor8->setEnabled(false); - m_aircraft->triYawChannel->setEnabled(false); - m_aircraft->mrRollMixLevel->setValue(100); - m_aircraft->mrPitchMixLevel->setValue(50); - m_aircraft->mrYawMixLevel->setValue(66); - - } else if (frameType == "Tri" || frameType == "Tricopter Y") { - m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor")); - m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Tricopter Y")); - quad->setElementId("tri"); - m_aircraft->multiMotor4->setEnabled(false); - m_aircraft->multiMotor5->setEnabled(false); - m_aircraft->multiMotor6->setEnabled(false); - m_aircraft->multiMotor7->setEnabled(false); - m_aircraft->multiMotor8->setEnabled(false); - m_aircraft->triYawChannel->setEnabled(true); - - } - m_aircraft->quadShape->setSceneRect(quad->boundingRect()); - m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); -} - -/** - Reset the contents of a field - */ -void ConfigAirframeWidget::resetField(UAVObjectField * field) -{ - for (unsigned int i=0;igetNumElements();i++) { - field->setValue(0,i); - } -} - -/** - Reset actuator values - */ -void ConfigAirframeWidget::resetActuators() -{ - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorSettings"))); - Q_ASSERT(obj); - QList fieldList = obj->getFields(); - // Reset all assignements first: - foreach (UAVObjectField* field, fieldList) { - // NOTE: we assume that all options in ActuatorSettings are a channel assignement - // except for the options called "ChannelXXX" - if (field->getUnits().contains("channel")) { - field->setValue(field->getOptions().last()); - } - } -} - -/** - Setup Elevator/Aileron/Rudder airframe. - - If both Aileron channels are set to 'None' (EasyStar), do Pitch/Rudder mixing - - Returns False if impossible to create the mixer. - */ -bool ConfigAirframeWidget::setupFrameFixedWing() -{ - // Check coherence: - // - At least Pitch and either Roll or Yaw - if (m_aircraft->fwEngineChannel->currentText() == "None" || - m_aircraft->fwElevator1Channel->currentText() == "None" || - ((m_aircraft->fwAileron1Channel->currentText() == "None") && - (m_aircraft->fwRudder1Channel->currentText() == "None"))) { - // TODO: explain the problem in the UI - m_aircraft->fwStatusLabel->setText("ERROR: check channel assignment"); - return false; - } - // Now setup the channels: - resetActuators(); - - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorSettings"))); - Q_ASSERT(obj); - - // Elevator - UAVObjectField *field = obj->getField("FixedWingPitch1"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwElevator1Channel->currentText()); - field = obj->getField("FixedWingPitch2"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwElevator2Channel->currentText()); - // Aileron - field = obj->getField("FixedWingRoll1"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwAileron1Channel->currentText()); - field = obj->getField("FixedWingRoll2"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwAileron2Channel->currentText()); - // Rudder - field = obj->getField("FixedWingYaw1"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwRudder1Channel->currentText()); - // Throttle - field = obj->getField("FixedWingThrottle"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwEngineChannel->currentText()); - - obj->updated(); - - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - // ... and compute the matrix: - // In order to make code a bit nicer, we assume: - // - Channel dropdowns start with 'None', then 0 to 7 - - // 1. Assign the servo/motor/none for each channel - // Disable all - foreach(QString mixer, mixerTypes) { - field = obj->getField(mixer); - Q_ASSERT(field); - field->setValue("Disabled"); - } - // and set only the relevant channels: - // Engine - int eng = m_aircraft->fwEngineChannel->currentIndex()-1; - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Motor"); - field = obj->getField(mixerVectors.at(eng)); - // First of all reset the vector - resetField(field); - int ti = field->getElementNames().indexOf("ThrottleCurve1"); - field->setValue(127, ti); - - // Rudder - eng = m_aircraft->fwRudder1Channel->currentIndex()-1; - // eng will be -1 if rudder is set to "None" - if (eng > -1) { - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Yaw"); - field->setValue(127, ti); - } // Else: we have no rudder, only ailerons, we're fine with it. - - // Ailerons - eng = m_aircraft->fwAileron1Channel->currentIndex()-1; - if (eng > -1) { - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Roll"); - field->setValue(127, ti); - // Only set Aileron 2 if Aileron 1 is defined - eng = m_aircraft->fwAileron2Channel->currentIndex()-1; - if (eng > -1) { - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Roll"); - field->setValue(127, ti); - } - } // Else we have no ailerons. Our consistency check guarantees we have - // rudder in this case, so we're fine with it too. - - // Elevator - eng = m_aircraft->fwElevator1Channel->currentIndex()-1; - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Pitch"); - field->setValue(127, ti); - // Only set Elevator 2 if it is defined - eng = m_aircraft->fwElevator2Channel->currentIndex()-1; - if (eng > -1) { - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Pitch"); - field->setValue(127, ti); - } - - obj->updated(); - m_aircraft->fwStatusLabel->setText("Mixer generated"); - - return true; -} - - -/** - Setup Elevon - */ -bool ConfigAirframeWidget::setupFrameElevon() -{ - // Check coherence: - // - At least Aileron1 and Aileron 2, and engine - if (m_aircraft->fwEngineChannel->currentText() == "None" || - m_aircraft->fwAileron1Channel->currentText() == "None" || - m_aircraft->fwAileron2Channel->currentText() == "None") { - // TODO: explain the problem in the UI - m_aircraft->fwStatusLabel->setText("ERROR: check channel assignment"); - return false; - } - - resetActuators(); - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorSettings"))); - Q_ASSERT(obj); - - // Elevons - UAVObjectField *field = obj->getField("FixedWingRoll1"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwAileron1Channel->currentText()); - field = obj->getField("FixedWingRoll2"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwAileron2Channel->currentText()); - // Rudder 1 (can be None) - field = obj->getField("FixedWingYaw1"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwRudder1Channel->currentText()); - // Rudder 2 (can be None) - field = obj->getField("FixedWingYaw2"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwRudder2Channel->currentText()); - // Throttle - field = obj->getField("FixedWingThrottle"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwEngineChannel->currentText()); - - obj->updated(); - - // Save the curve: - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - // ... and compute the matrix: - // In order to make code a bit nicer, we assume: - // - Channel dropdowns start with 'None', then 0 to 7 - - // 1. Assign the servo/motor/none for each channel - // Disable all - foreach(QString mixer, mixerTypes) { - field = obj->getField(mixer); - Q_ASSERT(field); - field->setValue("Disabled"); - } - // and set only the relevant channels: - // Engine - int eng = m_aircraft->fwEngineChannel->currentIndex()-1; - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Motor"); - field = obj->getField(mixerVectors.at(eng)); - // First of all reset the vector - resetField(field); - int ti = field->getElementNames().indexOf("ThrottleCurve1"); - field->setValue(127, ti); - - // Rudder 1 - eng = m_aircraft->fwRudder1Channel->currentIndex()-1; - // eng will be -1 if rudder 1 is set to "None" - if (eng > -1) { - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Yaw"); - field->setValue(127, ti); - } // Else: we have no rudder, only elevons, we're fine with it. - - // Rudder 2 - eng = m_aircraft->fwRudder2Channel->currentIndex()-1; - // eng will be -1 if rudder 2 is set to "None" - if (eng > -1) { - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Yaw"); - field->setValue(-127, ti); - } // Else: we have no rudder, only elevons, we're fine with it. - - eng = m_aircraft->fwAileron1Channel->currentIndex()-1; - if (eng > -1) { - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Pitch"); - field->setValue((double)m_aircraft->elevonSlider2->value()*1.27, ti); - ti = field->getElementNames().indexOf("Roll"); - field->setValue((double)m_aircraft->elevonSlider1->value()*1.27,ti); - } - - eng = m_aircraft->fwAileron2Channel->currentIndex()-1; - if (eng > -1) { - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Pitch"); - field->setValue((double)m_aircraft->elevonSlider2->value()*1.27, ti); - ti = field->getElementNames().indexOf("Roll"); - field->setValue(-(double)m_aircraft->elevonSlider1->value()*1.27,ti); - } - - obj->updated(); - m_aircraft->fwStatusLabel->setText("Mixer generated"); - return true; -} - -/** - Setup VTail - */ -bool ConfigAirframeWidget::setupFrameVtail() -{ - // Check coherence: - // - At least Pitch1 and Pitch2, and engine - if (m_aircraft->fwEngineChannel->currentText() == "None" || - m_aircraft->fwElevator1Channel->currentText() == "None" || - m_aircraft->fwElevator2Channel->currentText() == "None") { - // TODO: explain the problem in the UI - m_aircraft->fwStatusLabel->setText("WARNING: check channel assignment"); - return false; - } - - resetActuators(); - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorSettings"))); - Q_ASSERT(obj); - - // Elevons - UAVObjectField *field = obj->getField("FixedWingPitch1"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwElevator1Channel->currentText()); - field = obj->getField("FixedWingPitch2"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwElevator2Channel->currentText()); - field = obj->getField("FixedWingRoll1"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwAileron1Channel->currentText()); - field = obj->getField("FixedWingRoll2"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwAileron2Channel->currentText()); - - // Throttle - field = obj->getField("FixedWingThrottle"); - Q_ASSERT(field); - field->setValue(m_aircraft->fwEngineChannel->currentText()); - - obj->updated(); - - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - // ... and compute the matrix: - // In order to make code a bit nicer, we assume: - // - Channel dropdowns start with 'None', then 0 to 7 - - // 1. Assign the servo/motor/none for each channel - // Disable all - foreach(QString mixer, mixerTypes) { - field = obj->getField(mixer); - Q_ASSERT(field); - field->setValue("Disabled"); - } - // and set only the relevant channels: - // Engine - int eng = m_aircraft->fwEngineChannel->currentIndex()-1; - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Motor"); - field = obj->getField(mixerVectors.at(eng)); - // First of all reset the vector - resetField(field); - int ti = field->getElementNames().indexOf("ThrottleCurve1"); - field->setValue(127, ti); - - eng = m_aircraft->fwAileron1Channel->currentIndex()-1; - if (eng > -1) { - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Roll"); - field->setValue(127,ti); - } - - eng = m_aircraft->fwAileron2Channel->currentIndex()-1; - if (eng > -1) { - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Roll"); - field->setValue(-127,ti); - } - - // Now compute the VTail - eng = m_aircraft->fwElevator1Channel->currentIndex()-1; - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Pitch"); - field->setValue((double)m_aircraft->elevonSlider2->value()*1.27, ti); - ti = field->getElementNames().indexOf("Yaw"); - field->setValue((double)m_aircraft->elevonSlider1->value()*1.27,ti); - - eng = m_aircraft->fwElevator2Channel->currentIndex()-1; - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - ti = field->getElementNames().indexOf("Pitch"); - field->setValue((double)m_aircraft->elevonSlider2->value()*1.27, ti); - ti = field->getElementNames().indexOf("Yaw"); - field->setValue(-(double)m_aircraft->elevonSlider1->value()*1.27,ti); - - obj->updated(); - m_aircraft->fwStatusLabel->setText("Mixer generated"); - return true; -} - -/** - Set up a complete mixer, taking a table of factors. The factors - shoudl mainly be +/- 1 factors, since they will be weighted by the - value of the Pitch/Roll/Yaw sliders. - - Example: - double xMixer [8][3] = { - P R Y - { 1, 1, -1}, Motor 1 - { 1, -1, 1}, Motor 2 - {-1, -1, -1}, Motor 3 - {-1, 1, 1}, ... - { 0, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0} - }; - */ -bool ConfigAirframeWidget::setupMixer(double mixerFactors[8][3]) -{ - UAVObjectField *field; - QList mmList; - mmList << m_aircraft->multiMotor1 << m_aircraft->multiMotor2 << m_aircraft->multiMotor3 - << m_aircraft->multiMotor4 << m_aircraft->multiMotor5 << m_aircraft->multiMotor6 - << m_aircraft->multiMotor7 << m_aircraft->multiMotor8; - UAVDataObject *obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - // 1. Assign the servo/motor/none for each channel - // Disable all - foreach(QString mixer, mixerTypes) { - field = obj->getField(mixer); - Q_ASSERT(field); - field->setValue("Disabled"); - } - // and enable only the relevant channels: - double pFactor = (double)m_aircraft->mrPitchMixLevel->value()/100; - double rFactor = (double)m_aircraft->mrRollMixLevel->value()/100; - double yFactor = (double)m_aircraft->mrYawMixLevel->value()/100; - for (int i=0 ; i<8; i++) { - int channel = mmList.at(i)->currentIndex()-1; - if (channel > -1) - setupQuadMotor(channel, mixerFactors[i][0]*pFactor, - rFactor*mixerFactors[i][1], yFactor*mixerFactors[i][2]); - } - // obj->updated(); // Let caller do this... - return true; -} - - -/** - Help function: setupQuadMotor - */ -void ConfigAirframeWidget::setupQuadMotor(int channel, double pitch, double roll, double yaw) -{ - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - UAVObjectField *field = obj->getField(mixerTypes.at(channel)); - field->setValue("Motor"); - field = obj->getField(mixerVectors.at(channel)); - // First of all reset the vector - resetField(field); - int ti = field->getElementNames().indexOf("ThrottleCurve1"); - field->setValue(127, ti); - ti = field->getElementNames().indexOf("Roll"); - field->setValue(roll*127,ti); - ti = field->getElementNames().indexOf("Pitch"); - field->setValue(pitch*127,ti); - ti = field->getElementNames().indexOf("Yaw"); - field->setValue(yaw*127,ti); -} - -/** - Helper function: setup motors. Takes a list of channel names in input. - */ -void ConfigAirframeWidget::setupMotors(QList motorList) -{ - resetActuators(); - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorSettings"))); - Q_ASSERT(obj); - UAVObjectField *field; - QList mmList; - mmList << m_aircraft->multiMotor1 << m_aircraft->multiMotor2 << m_aircraft->multiMotor3 - << m_aircraft->multiMotor4 << m_aircraft->multiMotor5 << m_aircraft->multiMotor6 - << m_aircraft->multiMotor7 << m_aircraft->multiMotor8; - foreach (QString motor, motorList) { - field = obj->getField(motor); - field->setValue(mmList.takeFirst()->currentText()); - } - // obj->updated(); // Do not Save, let the caller do it... -} - - -/** - Set up a Quad-X or Quad-P -*/ -bool ConfigAirframeWidget::setupQuad(bool pLayout) -{ - // Check coherence: - // - Four engines have to be defined - if (m_aircraft->multiMotor1->currentText() == "None" || - m_aircraft->multiMotor2->currentText() == "None" || - m_aircraft->multiMotor3->currentText() == "None" || - m_aircraft->multiMotor4->currentText() == "None") { - m_aircraft->mrStatusLabel->setText("ERROR: Assign 4 motor channels"); - return false; - } - - - QList motorList; - if (pLayout) { - motorList << "VTOLMotorN" << "VTOLMotorE" << "VTOLMotorS" - << "VTOLMotorW"; - } else { - motorList << "VTOLMotorNW" << "VTOLMotorNE" << "VTOLMotorSE" - << "VTOLMotorSW"; - } - setupMotors(motorList); - - // Now, setup the mixer: - // Motor 1 to 4, X Layout: - // pitch roll yaw - // {0.5 ,0.5 ,-0.5 //Front left motor (CW) - // {0.5 ,-0.5 ,0.5 //Front right motor(CCW) - // {-0.5 ,-0.5 ,-0.5 //rear right motor (CW) - // {-0.5 ,0.5 ,0.5 //Rear left motor (CCW) - double xMixer [8][3] = { - { 1, 1, -1}, - { 1, -1, 1}, - {-1, -1, -1}, - {-1, 1, 1}, - { 0, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0} - }; - // - // Motor 1 to 4, P Layout: - // pitch roll yaw - // {1 ,0 ,-0.5 //Front motor (CW) - // {0 ,-1 ,0.5 //Right motor(CCW) - // {-1 ,0 ,-0.5 //Rear motor (CW) - // {0 ,1 ,0.5 //Left motor (CCW) - double pMixer [8][3] = { - { 1, 0, -1}, - { 0, -1, 1}, - {-1, 0, -1}, - { 0, 1, 1}, - { 0, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0} - }; - - if (pLayout) { - setupMixer(pMixer); - } else { - setupMixer(xMixer); - } - m_aircraft->mrStatusLabel->setText("SUCCESS: Mixer Saved OK"); - return true; -} - - - -/** - Set up a Hexa-X or Hexa-P -*/ -bool ConfigAirframeWidget::setupHexa(bool pLayout) -{ - // Check coherence: - // - Four engines have to be defined - if (m_aircraft->multiMotor1->currentText() == "None" || - m_aircraft->multiMotor2->currentText() == "None" || - m_aircraft->multiMotor3->currentText() == "None" || - m_aircraft->multiMotor4->currentText() == "None" || - m_aircraft->multiMotor5->currentText() == "None" || - m_aircraft->multiMotor6->currentText() == "None") { - m_aircraft->mrStatusLabel->setText("ERROR: Assign 6 motor channels"); - return false; - } - - QList motorList; - if (pLayout) { - motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorSE" - << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorNW"; - } else { - motorList << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" - << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW"; - } - setupMotors(motorList); - - // and set only the relevant channels: - - // Motor 1 to 6, P Layout: - // pitch roll yaw - // 1 { 0.3 , 0 ,-0.3 // N CW - // 2 { 0.3 ,-0.5 , 0.3 // NE CCW - // 3 {-0.3 ,-0.5 ,-0.3 // SE CW - // 4 {-0.3 , 0 , 0.3 // S CCW - // 5 {-0.3 , 0.5 ,-0.3 // SW CW - // 6 { 0.3 , 0.5 , 0.3 // NW CCW - - double pMixer [8][3] = { - { 1, 0, -1}, - { 1, -1, 1}, - {-1, -1, -1}, - {-1, 0, 1}, - {-1, 1, -1}, - { 1, 1, 1}, - { 0, 0, 0}, - { 0, 0, 0} - }; - - // - // Motor 1 to 6, X Layout: - // 1 [ 0.5, -0.3, -0.3 ] NE - // 2 [ 0 , -0.3, 0.3 ] E - // 3 [ -0.5, -0.3, -0.3 ] SE - // 4 [ -0.5, 0.3, 0.3 ] SW - // 5 [ 0 , 0.3, -0.3 ] W - // 6 [ 0.5, 0.3, 0.3 ] NW - double xMixer [8][3] = { - { 1, -1, -1}, - { 0, -1, 1}, - { -1, -1, -1}, - { -1, 1, 1}, - { 0, 1, -1}, - { 1, 1, 1}, - { 0, 0, 0}, - { 0, 0, 0} - }; - - if (pLayout) { - setupMixer(pMixer); - } else { - setupMixer(xMixer); - } - m_aircraft->mrStatusLabel->setText("SUCCESS: Mixer Saved OK"); - return true; -} - -/** - Updates the custom airframe settings based on the current airframe. - - Note: does NOT ask for an object refresh itself! - */ -void ConfigAirframeWidget::updateCustomAirframeUI() -{ - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - UAVObjectField* field = obj->getField(QString("ThrottleCurve1")); - QList curveValues; - // If the 1st element of the curve is <= -10, then the curve - // is a straight line (that's how the mixer works on the mainboard): - if (field->getValue(0).toInt() <= -10) { - for (double i=0; igetNumElements(); i++) { - curveValues.append(i/(field->getNumElements()-1)); - } - } else { - for (unsigned int i=0; i < field->getNumElements(); i++) { - curveValues.append(field->getValue(i).toDouble()); - } - } - m_aircraft->customThrottle1Curve->initCurve(curveValues); - - field = obj->getField(QString("ThrottleCurve2")); - curveValues.clear();; - // If the 1st element of the curve is <= -10, then the curve - // is a straight line (that's how the mixer works on the mainboard): - if (field->getValue(0).toInt() <= -10) { - for (double i=0; igetNumElements(); i++) { - curveValues.append(i/(field->getNumElements()-1)); - } - } else { - for (unsigned int i=0; i < field->getNumElements(); i++) { - curveValues.append(field->getValue(i).toDouble()); - } - } - m_aircraft->customThrottle2Curve->initCurve(curveValues); - - // Retrieve Feed Forward: - field = obj->getField(QString("FeedForward")); - m_aircraft->customFFSlider->setValue(field->getDouble()*100); - field = obj->getField(QString("AccelTime")); - m_aircraft->customFFaccel->setValue(field->getDouble()); - field = obj->getField(QString("DecelTime")); - m_aircraft->customFFdecel->setValue(field->getDouble()); - field = obj->getField(QString("MaxAccel")); - m_aircraft->customFFMaxAccel->setValue(field->getDouble()); - - // Update the table: - for (int i=0; i<8; i++) { - field = obj->getField(mixerTypes.at(i)); - QComboBox* q = (QComboBox*)m_aircraft->customMixerTable->cellWidget(0,i); - QString s = field->getValue().toString(); - q->setCurrentIndex(q->findText(s)); - //bool en = (s != "Disabled"); - field = obj->getField(mixerVectors.at(i)); - int ti = field->getElementNames().indexOf("ThrottleCurve1"); - m_aircraft->customMixerTable->item(1,i)->setText(field->getValue(ti).toString()); - ti = field->getElementNames().indexOf("ThrottleCurve2"); - m_aircraft->customMixerTable->item(2,i)->setText(field->getValue(ti).toString()); - ti = field->getElementNames().indexOf("Roll"); - m_aircraft->customMixerTable->item(3,i)->setText(field->getValue(ti).toString()); - ti = field->getElementNames().indexOf("Pitch"); - m_aircraft->customMixerTable->item(4,i)->setText(field->getValue(ti).toString()); - ti = field->getElementNames().indexOf("Yaw"); - m_aircraft->customMixerTable->item(5,i)->setText(field->getValue(ti).toString()); - } -} - - -/** - Sends the config to the board (airframe type) - - We do all the tasks common to all airframes, or family of airframes, and - we call additional methods for specific frames, so that we do not have a code - that is too heavy. -*/ -void ConfigAirframeWidget::sendAircraftUpdate() -{ - QString airframeType = "Custom"; - if (m_aircraft->aircraftType->currentText() == "Fixed Wing") { - // Save the curve (common to all Fixed wing frames) - UAVDataObject *obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - // Remove Feed Forward, it is pointless on a plane: - UAVObjectField* field = obj->getField(QString("FeedForward")); - field->setDouble(0); - field = obj->getField("ThrottleCurve1"); - QList curve = m_aircraft->fixedWingThrottle->getCurve(); - for (int i=0;isetValue(curve.at(i),i); - } - - if (m_aircraft->fixedWingType->currentText() == "Elevator aileron rudder" ) { - airframeType = "FixedWing"; - setupFrameFixedWing(); - } else if (m_aircraft->fixedWingType->currentText() == "Elevon") { - airframeType = "FixedWingElevon"; - setupFrameElevon(); - } else { // "Vtail" - airframeType = "FixedWingVtail"; - setupFrameVtail(); - } - // Now reflect those settings in the "Custom" panel as well - updateCustomAirframeUI(); - } else if (m_aircraft->aircraftType->currentText() == "Multirotor") { - - QList motorList; - - // We can already setup the feedforward here, as it is common to all platforms - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - UAVObjectField* field = obj->getField(QString("FeedForward")); - field->setDouble((double)m_aircraft->feedForwardSlider->value()/100); - field = obj->getField(QString("AccelTime")); - field->setDouble(m_aircraft->accelTime->value()); - field = obj->getField(QString("DecelTime")); - field->setDouble(m_aircraft->decelTime->value()); - field = obj->getField(QString("MaxAccel")); - field->setDouble(m_aircraft->maxAccelSlider->value()); - - // Curve is also common to all quads: - field = obj->getField("ThrottleCurve1"); - QList curve = m_aircraft->multiThrottleCurve->getCurve(); - for (int i=0;isetValue(curve.at(i),i); - } - - 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() == "Octocopter") { - airframeType = "Octo"; - if (m_aircraft->multiMotor1->currentText() == "None" || - m_aircraft->multiMotor2->currentText() == "None" || - m_aircraft->multiMotor3->currentText() == "None" || - m_aircraft->multiMotor4->currentText() == "None" || - m_aircraft->multiMotor5->currentText() == "None" || - m_aircraft->multiMotor6->currentText() == "None" || - m_aircraft->multiMotor7->currentText() == "None" || - m_aircraft->multiMotor8->currentText() == "None") { - m_aircraft->mrStatusLabel->setText("ERROR: Assign 8 motor channels"); - return; - } - motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" - << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW"; - setupMotors(motorList); - // Motor 1 to 8: - // pitch roll yaw - double mixer [8][3] = { - { 1, 0, -1}, - { 1, -1, 1}, - { 0, -1, -1}, - { -1, -1, 1}, - { -1, 0, -1}, - { -1, 1, 1}, - { 0, 1, -1}, - { 1, 1, 1} - }; - setupMixer(mixer); - m_aircraft->mrStatusLabel->setText("SUCCESS: Mixer Saved OK"); - - } else if (m_aircraft->multirotorFrameType->currentText() == "Hexacopter X") { - airframeType = "HexaX"; - setupHexa(false); - } else if (m_aircraft->multirotorFrameType->currentText() == "Octocopter V") { - airframeType = "OctoV"; - if (m_aircraft->multiMotor1->currentText() == "None" || - m_aircraft->multiMotor2->currentText() == "None" || - m_aircraft->multiMotor3->currentText() == "None" || - m_aircraft->multiMotor4->currentText() == "None" || - m_aircraft->multiMotor5->currentText() == "None" || - m_aircraft->multiMotor6->currentText() == "None" || - m_aircraft->multiMotor7->currentText() == "None" || - m_aircraft->multiMotor8->currentText() == "None") { - m_aircraft->mrStatusLabel->setText("ERROR: Assign 8 motor channels"); - return; - } - motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" - << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW"; - setupMotors(motorList); - // Motor 1 to 8: - // IMPORTANT: Assumes evenly spaced engines - // pitch roll yaw - double mixer [8][3] = { - { 0.33, -1, -1}, - { 1 , -1, 1}, - { -1 , -1, -1}, - { -0.33, -1, 1}, - { -0.33, 1, -1}, - { -1 , 1, 1}, - { 1 , 1, -1}, - { 0.33, 1, 1} - }; - setupMixer(mixer); - m_aircraft->mrStatusLabel->setText("SUCCESS: Mixer Saved OK"); - - } else if (m_aircraft->multirotorFrameType->currentText() == "Octo Coax +") { - airframeType = "OctoCoaxP"; - if (m_aircraft->multiMotor1->currentText() == "None" || - m_aircraft->multiMotor2->currentText() == "None" || - m_aircraft->multiMotor3->currentText() == "None" || - m_aircraft->multiMotor4->currentText() == "None" || - m_aircraft->multiMotor5->currentText() == "None" || - m_aircraft->multiMotor6->currentText() == "None" || - m_aircraft->multiMotor7->currentText() == "None" || - m_aircraft->multiMotor8->currentText() == "None") { - m_aircraft->mrStatusLabel->setText("ERROR: Assign 8 motor channels"); - return; - } - motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" - << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW"; - setupMotors(motorList); - // Motor 1 to 8: - // pitch roll yaw - double mixer [8][3] = { - { 1, 0, -1}, - { 1, 0, 1}, - { 0, -1, -1}, - { 0, -1, 1}, - { -1, 0, -1}, - { -1, 0, 1}, - { 0, 1, -1}, - { 0, 1, 1} - }; - setupMixer(mixer); - m_aircraft->mrStatusLabel->setText("SUCCESS: Mixer Saved OK"); - - } else if (m_aircraft->multirotorFrameType->currentText() == "Octo Coax X") { - airframeType = "OctoCoaxX"; - if (m_aircraft->multiMotor1->currentText() == "None" || - m_aircraft->multiMotor2->currentText() == "None" || - m_aircraft->multiMotor3->currentText() == "None" || - m_aircraft->multiMotor4->currentText() == "None" || - m_aircraft->multiMotor5->currentText() == "None" || - m_aircraft->multiMotor6->currentText() == "None" || - m_aircraft->multiMotor7->currentText() == "None" || - m_aircraft->multiMotor8->currentText() == "None") { - m_aircraft->mrStatusLabel->setText("ERROR: Assign 8 motor channels"); - return; - } - motorList << "VTOLMotorNW" << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" - << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW"; - setupMotors(motorList); - // Motor 1 to 8: - // pitch roll yaw - double mixer [8][3] = { - { 1, 1, -1}, - { 1, 1, 1}, - { 1, -1, -1}, - { 1, -1, 1}, - { -1, -1, -1}, - { -1, -1, 1}, - { -1, 1, -1}, - { -1, 1, 1} - }; - setupMixer(mixer); - m_aircraft->mrStatusLabel->setText("SUCCESS: Mixer Saved OK"); - - } else if (m_aircraft->multirotorFrameType->currentText() == "Hexacopter Y6") { - airframeType = "HexaCoax"; - if (m_aircraft->multiMotor1->currentText() == "None" || - m_aircraft->multiMotor2->currentText() == "None" || - m_aircraft->multiMotor3->currentText() == "None" || - m_aircraft->multiMotor4->currentText() == "None" || - m_aircraft->multiMotor5->currentText() == "None" || - m_aircraft->multiMotor6->currentText() == "None" ) { - m_aircraft->mrStatusLabel->setText("ERROR: Assign 6 motor channels"); - return; - } - motorList << "VTOLMotorNW" << "VTOLMotorW" << "VTOLMotorNE" << "VTOLMotorE" - << "VTOLMotorS" << "VTOLMotorSE"; - setupMotors(motorList); - - // Motor 1 to 6, Y6 Layout: - // pitch roll yaw - double mixer [8][3] = { - { 0.5, 1, -1}, - { 0.5, 1, 1}, - { 0.5, -1, -1}, - { 0.5, -1, 1}, - { -1, 0, -1}, - { -1, 0, 1}, - { 0, 0, 0}, - { 0, 0, 0} - }; - setupMixer(mixer); - m_aircraft->mrStatusLabel->setText("SUCCESS: Mixer Saved OK"); - - } else if (m_aircraft->multirotorFrameType->currentText() == "Tricopter Y") { - airframeType = "Tri"; - if (m_aircraft->multiMotor1->currentText() == "None" || - m_aircraft->multiMotor2->currentText() == "None" || - m_aircraft->multiMotor3->currentText() == "None" ) { - m_aircraft->mrStatusLabel->setText("ERROR: Assign 3 motor channels"); - return; - } - if (m_aircraft->triYawChannel->currentText() == "None") { - m_aircraft->mrStatusLabel->setText("Error: Assign a Yaw channel"); - return; - } - obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorSettings"))); - Q_ASSERT(obj); - motorList << "VTOLMotorNW" << "VTOLMotorNE" << "VTOLMotorS"; - setupMotors(motorList); - field = obj->getField("FixedWingYaw1"); - field->setValue(m_aircraft->triYawChannel->currentText()); - - // Motor 1 to 6, Y6 Layout: - // pitch roll yaw - double mixer [8][3] = { - { 0.5, 1, 0}, - { 0.5, -1, 0}, - { -1, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0} - }; - setupMixer(mixer); - - int eng = m_aircraft->triYawChannel->currentIndex()-1; - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - field = obj->getField(mixerTypes.at(eng)); - field->setValue("Servo"); - field = obj->getField(mixerVectors.at(eng)); - resetField(field); - int ti = field->getElementNames().indexOf("Yaw"); - field->setValue(127,ti); - - m_aircraft->mrStatusLabel->setText("SUCCESS: Mixer Saved OK"); - - } - // Now reflect those settings in the "Custom" panel as well - updateCustomAirframeUI(); - - } else if (m_aircraft->aircraftType->currentText() == "Helicopter") { - airframeType = "HeliCP"; - m_aircraft->widget_3->sendccpmUpdate(); - } else { - airframeType = "Custom"; - - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - UAVObjectField* field = obj->getField(QString("FeedForward")); - field->setDouble((double)m_aircraft->customFFSlider->value()/100); - field = obj->getField(QString("AccelTime")); - field->setDouble(m_aircraft->customFFaccel->value()); - field = obj->getField(QString("DecelTime")); - field->setDouble(m_aircraft->customFFdecel->value()); - field = obj->getField(QString("MaxAccel")); - field->setDouble(m_aircraft->customFFMaxAccel->value()); - - // Curve is also common to all quads: - field = obj->getField("ThrottleCurve1"); - QList curve = m_aircraft->customThrottle1Curve->getCurve(); - for (int i=0;isetValue(curve.at(i),i); - } - - field = obj->getField("ThrottleCurve2"); - curve.clear(); - curve = m_aircraft->customThrottle2Curve->getCurve(); - for (int i=0;isetValue(curve.at(i),i); - } - - // Update the table: - for (int i=0; i<8; i++) { - field = obj->getField(mixerTypes.at(i)); - QComboBox* q = (QComboBox*)m_aircraft->customMixerTable->cellWidget(0,i); - field->setValue(q->currentText()); - field = obj->getField(mixerVectors.at(i)); - int ti = field->getElementNames().indexOf("ThrottleCurve1"); - field->setValue(m_aircraft->customMixerTable->item(1,i)->text(),ti); - ti = field->getElementNames().indexOf("ThrottleCurve2"); - field->setValue(m_aircraft->customMixerTable->item(2,i)->text(),ti); - ti = field->getElementNames().indexOf("Roll"); - field->setValue(m_aircraft->customMixerTable->item(3,i)->text(),ti); - ti = field->getElementNames().indexOf("Pitch"); - field->setValue(m_aircraft->customMixerTable->item(4,i)->text(),ti); - ti = field->getElementNames().indexOf("Yaw"); - field->setValue(m_aircraft->customMixerTable->item(5,i)->text(),ti); - } - - // obj->updated(); - } - - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorSettings"))); - Q_ASSERT(obj); - obj->updated(); - - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - obj->updated(); - - obj = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings"))); - UAVObjectField* field = obj->getField(QString("AirframeType")); - field->setValue(airframeType); - obj->updated(); -} - -/** - Send airframe type to the board and request saving to SD card - */ -void ConfigAirframeWidget::saveAircraftUpdate() -{ - // Send update so that the latest value is saved - sendAircraftUpdate(); - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings"))); - Q_ASSERT(obj); - saveObjectToSD(obj); - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - saveObjectToSD(obj); - obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorSettings"))); - saveObjectToSD(obj); - -} - diff --git a/ground/openpilotgcs/src/plugins/config/configgadgetfactory.cpp b/ground/openpilotgcs/src/plugins/config/configgadgetfactory.cpp index 37447b01a..f19c3dac8 100644 --- a/ground/openpilotgcs/src/plugins/config/configgadgetfactory.cpp +++ b/ground/openpilotgcs/src/plugins/config/configgadgetfactory.cpp @@ -32,7 +32,7 @@ #include ConfigGadgetFactory::ConfigGadgetFactory(QObject *parent) : - IUAVGadgetFactory(QString("ConfigGadget"), tr("Config Gadget"), parent) + IUAVGadgetFactory(QString("ConfigGadget"), tr("Config"), parent) { } @@ -50,8 +50,3 @@ IUAVGadgetConfiguration *ConfigGadgetFactory::createConfiguration(QSettings* qSe { return new ConfigGadgetConfiguration(QString("ConfigGadget"), qSettings); } - -IOptionsPage *ConfigGadgetFactory::createOptionsPage(IUAVGadgetConfiguration *config) -{ - return new ConfigGadgetOptionsPage(qobject_cast(config)); -} diff --git a/ground/openpilotgcs/src/plugins/config/configgadgetfactory.h b/ground/openpilotgcs/src/plugins/config/configgadgetfactory.h index 8d371e746..de90e6def 100644 --- a/ground/openpilotgcs/src/plugins/config/configgadgetfactory.h +++ b/ground/openpilotgcs/src/plugins/config/configgadgetfactory.h @@ -46,7 +46,6 @@ public: IUAVGadget *createGadget(QWidget *parent); IUAVGadgetConfiguration *createConfiguration(QSettings* qSettings); - IOptionsPage *createOptionsPage(IUAVGadgetConfiguration *config); }; #endif // CONFIGGADGETFACTORY_H diff --git a/ground/openpilotgcs/src/plugins/coreplugin/OpenPilotGCS.xml b/ground/openpilotgcs/src/plugins/coreplugin/OpenPilotGCS.xml new file mode 100644 index 000000000..d46f83424 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/coreplugin/OpenPilotGCS.xml @@ -0,0 +1,2832 @@ + + + en_AU + true + + + 0 + + + #666666 + false + true + + + + + false + 1.0.0 + + + + + + + 0 + + + + + + + + + 0 + + 1 + + false + + 0 + + + + + + + + + false + 0.0.0 + + + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/default/attitude.svg + foreground + needle + needle + needle3 + Ubuntu,11,-1,5,50,0,0,0,0,0 + AttitudeActual + -1 + 360 + 0 + Rotate + Roll + AttitudeActual + 75 + 20 + 0 + Vertical + Pitch + AttitudeActual + -1 + 360 + 0 + Rotate + Roll + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/default/altimeter.svg + foreground + needle + needle2 + needle3 + Ubuntu,11,-1,5,50,0,0,0,0,0 + BaroAltitude + 1 + 10 + 0 + Rotate + Altitude + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/default/barometer.svg + + needle + + + Ubuntu,11,-1,5,50,0,0,0,0,0 + BaroAltitude + 10 + 1120 + 1000 + Rotate + Pressure + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/default/vsi.svg + + needle + + + Ubuntu,11,-1,5,50,0,0,0,0,0 + VelocityActual + 0.01 + 12 + -12 + Rotate + Down + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/default/compass.svg + foreground + needle + + + Ubuntu,11,-1,5,50,0,0,0,0,0 + AttitudeActual + -1 + 360 + 0 + Rotate + Yaw + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/deluxe/attitude.svg + foreground + needle + needle + needle3 + Ubuntu,11,-1,5,50,0,0,0,0,0 + AttitudeActual + -1 + 360 + 0 + Rotate + Roll + AttitudeActual + 75 + 20 + 0 + Vertical + Pitch + AttitudeActual + -1 + 360 + 0 + Rotate + Roll + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/deluxe/altimeter.svg + foreground + needle + needle2 + needle3 + Ubuntu,11,-1,5,50,0,0,0,0,0 + BaroAltitude + 1 + 10 + 0 + Rotate + Altitude + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/deluxe/barometer.svg + foreground + needle + + + Ubuntu,11,-1,5,50,0,0,0,0,0 + BaroAltitude + 10 + 1120 + 1000 + Rotate + Pressure + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/deluxe/vsi.svg + foreground + needle + + + Ubuntu,11,-1,5,50,0,0,0,0,0 + VelocityActual + 0.01 + 11.2 + -11.2 + Rotate + Down + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/deluxe/compass.svg + foreground + needle + + + Ubuntu,11,-1,5,50,0,0,0,0,0 + AttitudeActual + -1 + 360 + 0 + Rotate + Yaw + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/deluxe/speed.svg + foreground + needle + + + Ubuntu,11,-1,5,50,0,0,0,0,0 + GPSPosition + 3.6 + 120 + 0 + Rotate + Groundspeed + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/deluxe/thermometer.svg + foreground + needle + needle2 + needle3 + Ubuntu,11,-1,5,50,0,0,0,0,0 + BaroAltitude + 1 + 120 + 0 + Rotate + Temperature + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + /home/lafargue/OP/OpenPilot/trunk/artwork/Dials/deluxe/turncoordinator.svg + foreground + needle + needle2 + needle2 + Ubuntu,11,-1,5,50,0,0,0,0,0 + AttitudeActual + -1 + 360 + 0 + Rotate + Roll + AttitudeRaw + 1 + 20 + -20 + Horizontal + accels-X + AttitudeRaw + -1 + 360 + 0 + Rotate + accels-X + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/default/speed.svg + + needle + + + Ubuntu,11,-1,5,50,0,0,0,0,0 + GPSPosition + 3.6 + 120 + 0 + Rotate + Groundspeed + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/hi-contrast/attitude.svg + foreground + needle + needle + needle3 + Ubuntu,11,-1,5,50,0,0,0,0,0 + AttitudeActual + -1 + 360 + 0 + Rotate + Roll + AttitudeActual + 75 + 20 + 0 + Vertical + Pitch + AttitudeActual + -1 + 360 + 0 + Rotate + Roll + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/hi-contrast/altimeter.svg + foreground + needle + needle2 + needle3 + Ubuntu,11,-1,5,50,0,0,0,0,0 + BaroAltitude + 1 + 10 + 0 + Rotate + Altitude + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/hi-contrast/barometer.svg + + needle + + + Ubuntu,11,-1,5,50,0,0,0,0,0 + BaroAltitude + 10 + 1120 + 1000 + Rotate + Pressure + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/hi-contrast/vsi.svg + + needle + + + Ubuntu,11,-1,5,50,0,0,0,0,0 + VelocityActual + 0.01 + 12 + -12 + Rotate + Down + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/hi-contrast/compass.svg + foreground + needle + + + Ubuntu,11,-1,5,50,0,0,0,0,0 + AttitudeActual + -1 + 360 + 0 + Rotate + Yaw + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/hi-contrast/speed.svg + + needle + + + Ubuntu,11,-1,5,50,0,0,0,0,0 + GPSPosition + 3.6 + 120 + 0 + Rotate + Groundspeed + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/hi-contrast/thermometer.svg + + needle + needle2 + needle3 + Ubuntu,11,-1,5,50,0,0,0,0,0 + BaroAltitude + 1 + 120 + 0 + Rotate + Temperature + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/default/thermometer.svg + + needle + needle2 + needle3 + Ubuntu,11,-1,5,50,0,0,0,0,0 + ManualControlCommand + 1 + 2000 + 1000 + Rotate + Channel-3 + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + false + 0.0.0 + + + false + background + %%DATAPATH%%dials/default/thermometer.svg + + needle + needle2 + needle3 + Ubuntu,11,-1,5,50,0,0,0,0,0 + BaroAltitude + 1 + 120 + 0 + Rotate + Temperature + BaroAltitude + 1 + 100 + 0 + Rotate + Altitude + BaroAltitude + 1 + 1000 + 0 + Rotate + Altitude + false + + + + + + + false + 0.0.0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0.1 + 3 + 0 + 0.1 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + false + false + true + false + false + false + false + false + 2 + 1 + 0 + 2 + 3 + + + + + + + false + 0.0.0 + + + Telemetry + 3 + 0 + 0 + Serial port 0 + 11 + 0 + + + + + false + 0.0.0 + + + Serial + 3 + 0 + 0 + Serial port 0 + 17 + 0 + + + + + + + false + 0.0.0 + + + \usr\games\fgfs + \usr\share\games\FlightGear + 127.0.0.1 + 9009 + + + false + 9010 + 127.0.0.1 + FG + true + + + + + false + 0.0.0 + + + \home\lafargue\X-Plane 9\X-Plane-i686 + \usr\share\games\FlightGear + 127.0.0.3 + 6756 + + + false + 49000 + 127.0.0.1 + X-Plane + false + + + + + + + false + 1.0.1 + + + gcs.ini + + + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-vertical.svg + 0 + 1 + Andale Mono,12,-1,5,75,0,0,0,0,0 + 50 + 0 + 100 + 0 + 100 + 80 + AhrsStatus + CPULoad + false + 80 + 50 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-horizontal.svg + 2 + 1 + Andale Mono,8,-1,5,50,0,0,0,0,0 + -9 + -10 + 11 + -11 + 11 + -11 + AttitudeRaw + accels-X + false + -5 + -11 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-horizontal.svg + 2 + 1 + Andale Mono,6,-1,5,50,0,0,0,0,0 + -9 + -10 + 11 + -11 + 11 + -11 + AttitudeRaw + accels-Y + false + -5 + -11 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-horizontal.svg + 2 + 1 + Andale Mono,8,-1,5,50,0,0,0,0,0 + -9 + -10 + 11 + -11 + 11 + -11 + AttitudeRaw + accels-Z + false + -5 + -11 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/arm-status.svg + 0 + 1 + ,12,-1,5,50,0,0,0,0,0 + 100 + 66 + 100 + 0 + 33 + 0 + FlightStatus + Armed + false + 66 + 33 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/textonly.svg + 0 + 0.001 + ,12,-1,5,50,0,0,0,0,0 + 100 + 66 + 100 + 0 + 33 + 0 + SystemStats + FlightTime + false + 66 + 33 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/flightmode-status.svg + 0 + 1 + ,12,-1,5,50,0,0,0,0,0 + 100 + 66 + 100 + 0 + 33 + 0 + FlightStatus + FlightMode + false + 66 + 33 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/gps-signal.svg + 0 + 1 + ,12,-1,5,50,0,0,0,0,0 + 0 + 0 + 12 + 0 + 0 + 0 + GPSPosition + Satellites + false + 0 + 0 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/gps-status.svg + 0 + 1 + ,12,-1,5,50,0,0,0,0,0 + 100 + 66 + 100 + 0 + 33 + 0 + GPSPosition + Status + false + 66 + 33 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-vertical.svg + 0 + 1 + Andale Mono,12,-1,5,75,0,0,0,0,0 + 50 + 0 + 100 + 0 + 100 + 80 + SystemStats + CPULoad + false + 80 + 50 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-vertical.svg + 2 + 1 + Andale Mono,12,-1,5,75,0,0,0,0,0 + 0.5 + -0.5 + 1 + -1 + 1 + -1 + ActuatorDesired + Pitch + false + 0.8 + -0.8 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-vertical.svg + 2 + 1 + Andale Mono,12,-1,5,75,0,0,0,0,0 + 0.5 + -0.5 + 1 + -1 + 1 + -1 + ManualControlCommand + Pitch + false + 0.8 + -0.8 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-vertical.svg + 2 + 1 + Andale Mono,12,-1,5,75,0,0,0,0,0 + 0.8 + 0.3 + 90 + -90 + 1 + 0 + AttitudeActual + Pitch + false + 0.9 + 0.1 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-vertical.svg + 2 + 1 + Andale Mono,12,-1,5,75,0,0,0,0,0 + 0.5 + -0.5 + 1 + -1 + 1 + -1 + ActuatorDesired + Roll + false + 0.8 + -0.8 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-vertical.svg + 2 + 1 + Andale Mono,12,-1,5,75,0,0,0,0,0 + 0.5 + -0.5 + 1 + -1 + 1 + -1 + ManualControlCommand + Roll + false + 0.8 + -0.8 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-horizontal.svg + 0 + 1 + Andale Mono,12,-1,5,75,0,0,0,0,0 + 650 + 0 + 1200 + 0 + 1200 + 900 + GCSTelemetryStats + RxDataRate + false + 900 + 650 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-horizontal.svg + 0 + 1 + Andale Mono,12,-1,5,75,0,0,0,0,0 + 650 + 0 + 1200 + 0 + 1200 + 900 + GCSTelemetryStats + TxDataRate + false + 900 + 650 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-vertical.svg + 2 + 1 + Andale Mono,12,-1,5,75,0,0,0,0,0 + 0.5 + 0 + 1 + 0 + 1 + 0.75 + ManualControlCommand + Throttle + false + 0.75 + 0.5 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-vertical.svg + 2 + 1 + Andale Mono,12,-1,5,75,0,0,0,0,0 + 0.5 + -0.5 + 1 + -1 + 1 + -1 + ActuatorDesired + Yaw + false + 0.8 + -0.8 + + + + + false + 0.0.0 + + + %%DATAPATH%%dials/default/lineardial-vertical.svg + 2 + 1 + Andale Mono,12,-1,5,75,0,0,0,0,0 + 0.5 + -0.5 + 1 + -1 + 1 + -1 + ManualControlCommand + Yaw + false + 0.8 + -0.8 + + + + + + + false + 0.0.0 + + + %%DATAPATH%%models/multi/aeroquad/aeroquad_+.3ds + %%DATAPATH%%models/backgrounds/default_background.png + false + + + + + false + 0.0.0 + + + %%DATAPATH%%models/multi/easy_quad/easy_quad_X.3ds + %%DATAPATH%%models/backgrounds/default_background.png + false + + + + + false + 0.0.0 + + + %%DATAPATH%%models/planes/Easystar/easystar.3ds + %%DATAPATH%%models/backgrounds/default_background.png + false + + + + + false + 0.0.0 + + + %%DATAPATH%%models/planes/firecracker/firecracker.3ds + %%DATAPATH%%models/backgrounds/default_background.png + false + + + + + false + 0.0.0 + + + %%DATAPATH%%models/planes/funjet/funjet.3ds + %%DATAPATH%%models/backgrounds/default_background.png + false + + + + + false + 0.0.0 + + + %%DATAPATH%%models/multi/gaui_330x/gaui_330x.3ds + %%DATAPATH%%models/backgrounds/default_background.png + false + + + + + false + 0.0.0 + + + %%DATAPATH%%models/helis/t-rex/t-rex_450_xl.3ds + %%DATAPATH%%models/backgrounds/default_background.png + false + + + + + false + 0.0.0 + + + %%DATAPATH%%models/multi/mikrokopter/MK_Hexa.3ds + %%DATAPATH%%models/backgrounds/default_background.png + false + + + + + false + 0.0.0 + + + %%DATAPATH%%models/multi/mikrokopter/MK_L4-ME.3ds + %%DATAPATH%%models/backgrounds/default_background.png + false + + + + + false + 0.0.0 + + + %%DATAPATH%%models/multi/scorpion_tricopter/scorpion_tricopter.3ds + %%DATAPATH%%models/backgrounds/default_background.png + false + + + + + false + 0.0.0 + + + %%DATAPATH%%models/multi/test_quad/test_quad_+.3ds + %%DATAPATH%%models/backgrounds/default_background.png + false + + + + + false + 0.0.0 + + + %%DATAPATH%%models/multi/test_quad/test_quad_X.3ds + %%DATAPATH%%models/backgrounds/default_background.png + false + + + + + + + false + 0.0.0 + + + ServerAndCache + %%STOREPATH%%mapscache/ + 0 + 0 + 2 + GoogleSatellite + 2000 + false + mapquad.png + true + false + + + + + false + 0.0.0 + + + CacheOnly + %%STOREPATH%%mapscache/ + 0 + 0 + 2 + GoogleMap + 2000 + false + airplanepip.png + true + false + + + + + false + 0.0.0 + + + ServerAndCache + %%STOREPATH%%mapscache/ + 0 + 0 + 2 + GoogleMap + 2000 + false + mapquad.png + true + false + + + + + + + false + 0.0.0 + + + false + %%DATAPATH%%pfd/default/pfd.svg + false + false + + + + + false + 0.0.0 + + + true + %%DATAPATH%%pfd/default/pfd.svg + false + false + + + + + + + false + 0.0.0 + + + + + + + false + 0.0.0 + + + false + false + + 1000 + 60 + + 4294901760 + accels-X + AttitudeRaw + 0 + 0 + 0 + + + 4283782655 + accels-Y + AttitudeRaw + 0 + 0 + 0 + + + 4283804160 + accels-Z + AttitudeRaw + 0 + 0 + 0 + + 3 + 1 + 100 + + + + + false + 0.0.0 + + + false + false + + 1000 + 20 + + 4294901760 + Channel-4 + ActuatorCommand + 0 + 0 + 0 + + + 4294901760 + Channel-5 + ActuatorCommand + 0 + 0 + 0 + + + 4289374847 + Channel-6 + ActuatorCommand + 0 + 0 + 0 + + + 4289374847 + Channel-7 + ActuatorCommand + 0 + 0 + 0 + + 4 + 1 + 100 + + + + + false + 0.0.0 + + + false + false + + 1000 + 60 + + 4283760895 + Roll + AttitudeActual + 0 + 0 + 0 + + + 4278233600 + Yaw + AttitudeActual + 0 + 0 + 0 + + + 4294901760 + Pitch + AttitudeActual + 0 + 0 + 0 + + 3 + 1 + 100 + + + + + false + 0.0.0 + + + false + false + + 1000 + 60 + + 4278190080 + Pressure + BaroAltitude + 0 + 0 + 0 + + 1 + 1 + 1000 + + + + + false + 0.0.0 + + + false + false + + 1000 + 40 + + 4278190207 + Channel-1 + ManualControlCommand + 0 + 0 + 0 + + + 4294901760 + Channel-4 + ManualControlCommand + 0 + 0 + 0 + + + 4294901760 + Channel-5 + ManualControlCommand + 0 + 0 + 0 + + + 4294901760 + Channel-6 + ManualControlCommand + 0 + 0 + 0 + + + 4294901760 + Channel-7 + ManualControlCommand + 0 + 0 + 0 + + + 4283825920 + Channel-2 + ManualControlCommand + 0 + 0 + 0 + + + 4294923520 + Channel-3 + ManualControlCommand + 0 + 0 + 0 + + + 4294967040 + Channel-0 + ManualControlCommand + 0 + 0 + 0 + + 8 + 1 + 200 + + + + + false + 0.0.0 + + + false + false + + 1000 + 60 + + 4294901760 + accels-X + AttitudeRaw + 0 + 0 + 0 + + + 4283782655 + accels-Y + AttitudeRaw + 0 + 0 + 0 + + + 4283804160 + accels-Z + AttitudeRaw + 0 + 0 + 0 + + 3 + 1 + 500 + + + + + false + 0.0.0 + + + false + false + + 1000 + 60 + + 4283804160 + gyros-Z + AttitudeRaw + 0 + 0 + 0 + + + 4283782655 + gyros-Y + AttitudeRaw + 0 + 0 + 0 + + + 4294901760 + gyros-X + AttitudeRaw + 0 + 0 + 0 + + 3 + 1 + 500 + + + + + false + 0.0.0 + + + false + false + + 1000 + 60 + + 4294901760 + magnetometers-X + AttitudeRaw + 0 + 0 + 0 + + + 4283782655 + magnetometers-Y + AttitudeRaw + 0 + 0 + 0 + + + 4283804160 + magnetometers-Z + AttitudeRaw + 0 + 0 + 0 + + 3 + 1 + 500 + + + + + false + 0.0.0 + + + false + false + + 1000 + 240 + + 4294945280 + StackRemaining-System + TaskInfo + 0 + 0 + 0 + + + 4294945280 + StackRemaining-Actuator + TaskInfo + 0 + 0 + 0 + + + 4294945280 + StackRemaining-Guidance + TaskInfo + 0 + 0 + 0 + + + 4294945280 + StackRemaining-Watchdog + TaskInfo + 0 + 0 + 0 + + + 4294945280 + StackRemaining-TelemetryTx + TaskInfo + 0 + 0 + 0 + + + 4294945280 + StackRemaining-TelemetryTxPri + TaskInfo + 0 + 0 + 0 + + + 4294945280 + StackRemaining-TelemetryRx + TaskInfo + 0 + 0 + 0 + + + 4294945280 + StackRemaining-GPS + TaskInfo + 0 + 0 + 0 + + + 4294945280 + StackRemaining-ManualControl + TaskInfo + 0 + 0 + 0 + + + 4294945280 + StackRemaining-Altitude + TaskInfo + 0 + 0 + 0 + + + 4294945280 + StackRemaining-AHRSComms + TaskInfo + 0 + 0 + 0 + + + 4294945280 + StackRemaining-Stabilization + TaskInfo + 0 + 0 + 0 + + 12 + 1 + 1000 + + + + + false + 0.0.0 + + + false + false + + 1000 + 20 + + 4289374847 + TxFailures + GCSTelemetryStats + 0 + 0 + 0 + + + 4283782655 + RxFailures + GCSTelemetryStats + 0 + 0 + 0 + + + 4294901760 + TxRetries + GCSTelemetryStats + 0 + 0 + 0 + + 3 + 1 + 100 + + + + + false + 0.0.0 + + + false + false + + 1000 + 240 + + 4289374847 + RunningTime + AhrsStatus + 0 + 0 + 0 + + + 4294945407 + FlightTime + SystemStats + 0 + 0 + 0 + + 2 + 1 + 800 + + + + + + + false + 0.0.0 + + + %%DATAPATH%%diagrams/default/system-health.svg + + + + + + + false + 0.0.0 + + + #5baa56 + #ff7957 + 500 + + + + + + + false + 0.0.0 + + + 3 + 0 + 0 + /dev/ttyS0 + 14 + 0 + + + + + false + 1.2.0 + + + + + false + + + + + + + LineardialGadget + + Flight Time + + uavGadget + + + LineardialGadget + + GPS Sats + + uavGadget + + 2 + @Variant(AAAACQAAAAA=) + splitter + + + + LineardialGadget + + Flight mode + + uavGadget + + + LineardialGadget + + Arm Status + + uavGadget + + 2 + @Variant(AAAACQAAAAA=) + splitter + + 2 + @Variant(AAAACQAAAAIAAAACAAAA1wAAAAIAAADt) + splitter + + + PFDGadget + + raw + + uavGadget + + 1 + @Variant(AAAACQAAAAIAAAACAAAAkAAAAAIAAAJg) + splitter + + + + ModelViewGadget + + Test Quad X + + uavGadget + + + + + SystemHealthGadget + + default + + uavGadget + + + + LineardialGadget + + Mainboard CPU + + uavGadget + + + LineardialGadget + + AHRS CPU + + uavGadget + + 1 + @Variant(AAAACQAAAAIAAAACAAAAQAAAAAIAAABA) + splitter + + 1 + @Variant(AAAACQAAAAIAAAACAAABIwAAAAIAAACN) + splitter + + + + LineardialGadget + + Telemetry RX Rate Horizontal + + uavGadget + + + LineardialGadget + + Telemetry TX Rate Horizontal + + uavGadget + + 1 + @Variant(AAAACQAAAAA=) + splitter + + 2 + @Variant(AAAACQAAAAIAAAACAAABJQAAAAIAAABA) + splitter + + 1 + @Variant(AAAACQAAAAIAAAACAAABMAAAAAIAAAGx) + splitter + + 2 + @Variant(AAAACQAAAAIAAAACAAABxQAAAAIAAAFH) + splitter + + + + OPMapGadget + + Google Sat + + uavGadget + + + + + + + DialGadget + + Deluxe Groundspeed kph + + uavGadget + + + DialGadget + + Deluxe Barometer + + uavGadget + + 2 + @Variant(AAAACQAAAAA=) + splitter + + + + DialGadget + + Deluxe Attitude + + uavGadget + + + DialGadget + + Deluxe Compass + + uavGadget + + 2 + @Variant(AAAACQAAAAA=) + splitter + + 1 + @Variant(AAAACQAAAAIAAAACAAAAgwAAAAIAAACK) + splitter + + + + DialGadget + + Deluxe Baro Altimeter + + uavGadget + + + DialGadget + + Deluxe Climbrate + + uavGadget + + 2 + @Variant(AAAACQAAAAA=) + splitter + + 1 + @Variant(AAAACQAAAAIAAAACAAABFQAAAAIAAACH) + splitter + + + + LineardialGadget + + Throttle + + uavGadget + + + + LineardialGadget + + Roll Desired + + uavGadget + + + + LineardialGadget + + Pitch Desired + + uavGadget + + + LineardialGadget + + Yaw Desired + + uavGadget + + 1 + @Variant(AAAACQAAAAIAAAACAAAAQAAAAAIAAAE3) + splitter + + 1 + @Variant(AAAACQAAAAIAAAACAAAAQAAAAAIAAAF4) + splitter + + 1 + @Variant(AAAACQAAAAIAAAACAAAAQAAAAAIAAAG5) + splitter + + 1 + @Variant(AAAACQAAAAIAAAACAAABuQAAAAIAAAED) + splitter + + 2 + @Variant(AAAACQAAAAIAAAACAAAB7AAAAAIAAAEg) + splitter + + 1 + @Variant(AAAACQAAAAIAAAACAAAC4gAAAAIAAAK9) + splitter + + UAVGadgetManagerV1 + + + false + + + + ConfigGadget + + default + + uavGadget + + + + LineardialGadget + + Telemetry RX Rate Horizontal + + uavGadget + + + LineardialGadget + + Telemetry TX Rate Horizontal + + uavGadget + + 1 + @Variant(AAAACQAAAAA=) + splitter + + 2 + @Variant(AAAACQAAAAIAAAACAAACNQAAAAIAAABC) + splitter + + + + UAVObjectBrowser + + default + + uavGadget + + + GCSControlGadget + + MS Sidewinder + + uavGadget + + 2 + @Variant(AAAACQAAAAIAAAACAAABqgAAAAIAAAFi) + splitter + + 1 + @Variant(AAAACQAAAAIAAAACAAAC3gAAAAIAAAJ3) + splitter + + UAVGadgetManagerV1 + + + false + + + OPMapGadget + + default + + uavGadget + + + + ModelViewGadget + + Test Quad X + + uavGadget + + + + DialGadget + + Attitude + + uavGadget + + + DialGadget + + Compass + + uavGadget + + 1 + @Variant(AAAACQAAAAA=) + splitter + + 2 + @Variant(AAAACQAAAAIAAAACAAABiwAAAAIAAADs) + splitter + + 1 + @Variant(AAAACQAAAAIAAAACAAAD1AAAAAIAAAGB) + splitter + + UAVGadgetManagerV1 + + + false + + + + ScopeGadget + + Accel + + uavGadget + + + ScopeGadget + + Raw Gyros + + uavGadget + + 2 + @Variant(AAAACQAAAAA=) + splitter + + + + + ScopeGadget + + Attitude + + uavGadget + + + ScopeGadget + + Uptimes + + uavGadget + + 2 + @Variant(AAAACQAAAAIAAAACAAABhgAAAAIAAAEO) + splitter + + + LoggingGadget + uavGadget + + 2 + @Variant(AAAACQAAAAIAAAACAAAClQAAAAIAAAB3) + splitter + + 1 + @Variant(AAAACQAAAAIAAAACAAACjQAAAAIAAAKU) + splitter + + UAVGadgetManagerV1 + + + false + + + + HITL + + XPlane HITL + + uavGadget + + + + GCSControlGadget + + MS Sidewinder + + uavGadget + + + + + LineardialGadget + + Pitch Desired + + uavGadget + + + LineardialGadget + + PitchActual + + uavGadget + + 1 + @Variant(AAAACQAAAAA=) + splitter + + + LineardialGadget + + Pitch + + uavGadget + + 1 + @Variant(AAAACQAAAAIAAAACAAABFAAAAAIAAABA) + splitter + + 1 + @Variant(AAAACQAAAAIAAAACAAAB6AAAAAIAAADC) + splitter + + 2 + @Variant(AAAACQAAAAIAAAACAAABaQAAAAIAAAEO) + splitter + + + UAVObjectBrowser + + default + + uavGadget + + 1 + @Variant(AAAACQAAAAIAAAACAAADDAAAAAIAAAJJ) + splitter + + UAVGadgetManagerV1 + + + false + + + Uploader + + default + + uavGadget + + + + + SystemHealthGadget + + default + + uavGadget + + + PFDGadget + + raw + + uavGadget + + 1 + @Variant(AAAACQAAAAIAAAACAAABQgAAAAIAAAGM) + splitter + + + ScopeGadget + + Uptimes + + uavGadget + + 2 + @Variant(AAAACQAAAAIAAAACAAABEgAAAAIAAAH6) + splitter + + 1 + @Variant(AAAACQAAAAA=) + splitter + + UAVGadgetManagerV1 + + + @ByteArray(AAAA/wAAAAD9AAAAAAAABQAAAALCAAAABAAAAAQAAAABAAAACPwAAAAA) + + :/core/images/ah.png + :/core/images/openpilot_logo_64.png + :/core/images/config.png + :/core/images/world.png + :/core/images/scopes.png + :/core/images/joystick.png + :/core/images/cog.png + :/core/images/openpilot_logo_64.png + :/core/images/openpilot_logo_64.png + :/core/images/openpilot_logo_64.png + 6 + Flight data + Workspace10 + Configuration + Flight Planner + Scopes + HITL + Firmware + Workspace7 + Workspace8 + Workspace9 + + diff --git a/ground/openpilotgcs/src/plugins/coreplugin/core.qrc b/ground/openpilotgcs/src/plugins/coreplugin/core.qrc index 917018476..5c6d9c76b 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/core.qrc +++ b/ground/openpilotgcs/src/plugins/coreplugin/core.qrc @@ -50,7 +50,6 @@ images/optionsicon.png images/helpicon.png images/openpiloticon.png - OpenPilotGCS.ini CREDITS.html images/ah.png images/config.png @@ -60,5 +59,6 @@ images/scopes.png images/world.png images/cog.png + OpenPilotGCS.xml diff --git a/ground/openpilotgcs/src/plugins/coreplugin/dialogs/ioptionspage.h b/ground/openpilotgcs/src/plugins/coreplugin/dialogs/ioptionspage.h index 1f470b97c..21a299508 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/dialogs/ioptionspage.h +++ b/ground/openpilotgcs/src/plugins/coreplugin/dialogs/ioptionspage.h @@ -32,6 +32,7 @@ #include #include +#include QT_BEGIN_NAMESPACE class QWidget; @@ -43,9 +44,14 @@ class CORE_EXPORT IOptionsPage : public QObject { Q_OBJECT public: - IOptionsPage(QObject *parent = 0) : QObject(parent) {} + IOptionsPage(QObject *parent = 0) : + QObject(parent), + m_icon(QIcon()) {} virtual ~IOptionsPage() {} + void setIcon(QIcon icon) { m_icon = icon; } + QIcon icon() { return m_icon; } + /* gadget options pages can leave these 4 functions as is, since they are decorated by UAVGadgetOptionsPageDecorator, all other options pages must override these */ @@ -57,6 +63,8 @@ public: virtual QWidget *createPage(QWidget *parent) = 0; virtual void apply() = 0; virtual void finish() = 0; +private: + QIcon m_icon; }; } // namespace Core diff --git a/ground/openpilotgcs/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/ground/openpilotgcs/src/plugins/coreplugin/dialogs/settingsdialog.cpp index 5e77125f0..413cdb63b 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/dialogs/settingsdialog.cpp +++ b/ground/openpilotgcs/src/plugins/coreplugin/dialogs/settingsdialog.cpp @@ -114,6 +114,7 @@ SettingsDialog::SettingsDialog(QWidget *parent, const QString &categoryId, splitter->setCollapsible(0, false); splitter->setCollapsible(1, false); pageTree->header()->setVisible(false); +// pageTree->setIconSize(QSize(24, 24)); connect(pageTree, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(pageSelected())); @@ -150,6 +151,7 @@ SettingsDialog::SettingsDialog(QWidget *parent, const QString &categoryId, } } categoryItem = new QTreeWidgetItem(pageTree); + categoryItem->setIcon(0, page->icon()); categoryItem->setText(0, trCategories); categoryItem->setData(0, Qt::UserRole, qVariantFromValue(pageData)); categories.insert(currentCategory, categoryItem); diff --git a/ground/openpilotgcs/src/plugins/coreplugin/iuavgadgetfactory.h b/ground/openpilotgcs/src/plugins/coreplugin/iuavgadgetfactory.h index 96fed8b28..5b8029241 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/iuavgadgetfactory.h +++ b/ground/openpilotgcs/src/plugins/coreplugin/iuavgadgetfactory.h @@ -31,6 +31,7 @@ #include "core_global.h" #include +#include #include #include "uavconfiginfo.h" @@ -51,7 +52,9 @@ public: IUAVGadgetFactory(QString classId, QString name, QObject *parent = 0) : QObject(parent), m_classId(classId), - m_name(name) {} + m_name(name), + m_icon(QIcon()), + m_singleConfigurationGadget(false) {} virtual ~IUAVGadgetFactory() {} virtual IUAVGadget *createGadget(QWidget *parent) = 0; @@ -60,9 +63,16 @@ public: virtual IOptionsPage *createOptionsPage(IUAVGadgetConfiguration */*config*/) { return 0; } QString classId() const { return m_classId; } QString name() const { return m_name; } + QIcon icon() const { return m_icon; } + bool isSingleConfigurationGadget() { return m_singleConfigurationGadget; } +protected: + void setIcon(QIcon icon) { m_icon = icon; } + void setSingleConfigurationGadgetTrue() { m_singleConfigurationGadget = true; } private: QString m_classId; // unique class id QString m_name; // display name, should also be unique + QIcon m_icon; + bool m_singleConfigurationGadget; // true if there is exactly one configuration for this gadget }; } // namespace Core diff --git a/ground/openpilotgcs/src/plugins/coreplugin/mainwindow.cpp b/ground/openpilotgcs/src/plugins/coreplugin/mainwindow.cpp index 3a1fc324e..19df8dde2 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/mainwindow.cpp +++ b/ground/openpilotgcs/src/plugins/coreplugin/mainwindow.cpp @@ -30,6 +30,7 @@ #include "actioncontainer.h" #include "actionmanager_p.h" #include "basemode.h" +#include "connectionmanager.h" #include "coreimpl.h" #include "coreconstants.h" #include "fancytabwidget.h" @@ -39,35 +40,34 @@ #include "mimedatabase.h" #include "outputpane.h" #include "plugindialog.h" +#include "qxtlogger.h" +#include "qxtbasicstdloggerengine.h" #include "shortcutsettings.h" -#include "workspacesettings.h" -#include "modemanager.h" #include "uavgadgetmode.h" #include "uavgadgetmanager.h" #include "uavgadgetinstancemanager.h" -#include "connectionmanager.h" -#include "qxtlogger.h" -#include "qxtbasicstdloggerengine.h" +#include "workspacesettings.h" -#include "settingsdialog.h" -#include "variablemanager.h" -#include "threadmanager.h" -#include "versiondialog.h" #include "authorsdialog.h" -#include "viewmanager.h" -#include "uniqueidmanager.h" -#include "manhattanstyle.h" -#include "dialogs/iwizard.h" -#include "rightpane.h" #include "baseview.h" #include "ioutputpane.h" #include "icorelistener.h" #include "iconfigurableplugin.h" +#include "manhattanstyle.h" +#include "rightpane.h" +#include "settingsdialog.h" +#include "threadmanager.h" +#include "uniqueidmanager.h" +#include "variablemanager.h" +#include "versiondialog.h" +#include "viewmanager.h" #include +#include +#include "dialogs/iwizard.h" #include #include -#include +#include #include #include @@ -112,9 +112,9 @@ MainWindow::MainWindow() : m_globalContext(QList() << Constants::C_GLOBAL_ID), m_additionalContexts(m_globalContext), // keep this in sync with main() in app/main.cpp - m_settings(new QSettings(QSettings::IniFormat, QSettings::UserScope, + m_settings(new QSettings(XmlConfig::XmlSettingsFormat, QSettings::UserScope, QLatin1String("OpenPilot"), QLatin1String("OpenPilotGCS"), this)), - m_globalSettings(new QSettings(QSettings::IniFormat, QSettings::SystemScope, + m_globalSettings(new QSettings(XmlConfig::XmlSettingsFormat, QSettings::SystemScope, QLatin1String("OpenPilot"), QLatin1String("OpenPilotGCS"), this)), m_settingsDatabase(new SettingsDatabase(QFileInfo(m_settings->fileName()).path(), QLatin1String("OpenPilotGCS"), @@ -155,7 +155,7 @@ MainWindow::MainWindow() : QCoreApplication::setApplicationVersion(QLatin1String(Core::Constants::GCS_VERSION_LONG)); QCoreApplication::setOrganizationName(QLatin1String("OpenPilot")); QCoreApplication::setOrganizationDomain(QLatin1String("openpilot.org")); - QSettings::setDefaultFormat(QSettings::IniFormat); + QSettings::setDefaultFormat(XmlConfig::XmlSettingsFormat); QString baseName = qApp->style()->objectName(); #ifdef Q_WS_X11 if (baseName == QLatin1String("windows")) { @@ -284,7 +284,8 @@ void MainWindow::extensionsInitialized() { QSettings* qs = m_settings; - QSettings defaultSettings(":/core/OpenPilotGCS.ini", QSettings::IniFormat); + QSettings defaultSettings(":/core/OpenPilotGCS.xml", XmlConfig::XmlSettingsFormat); +// QSettings defaultSettings(":/core/OpenPilotGCS.ini", QSettings::IniFormat); if ( ! qs->allKeys().count() ){ QMessageBox msgBox; @@ -293,7 +294,7 @@ void MainWindow::extensionsInitialized() msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); if ( msgBox.exec() == QMessageBox::Yes ){ - qDebug() << "Load default config from resource /core/OpenPilotGCS.ini"; + qDebug() << "Load default config from resource /core/OpenPilotGCS.xml"; qs = &defaultSettings; } } diff --git a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.cpp b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.cpp index f93e5cb60..55dc239a8 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.cpp +++ b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.cpp @@ -56,7 +56,9 @@ UAVGadgetInstanceManager::UAVGadgetInstanceManager(QObject *parent) : m_factories.append(f); QString classId = f->classId(); QString name = f->name(); - m_classIds.insert(classId, name); + QIcon icon = f->icon(); + m_classIdNameMap.insert(classId, name); + m_classIdIconMap.insert(classId, icon); } } } @@ -108,7 +110,7 @@ void UAVGadgetInstanceManager::readConfigs_1_2_0(QSettings *qs) { UAVConfigInfo configInfo; - foreach (QString classId, m_classIds.keys()) + foreach (QString classId, m_classIdNameMap.keys()) { IUAVGadgetFactory *f = factory(classId); qs->beginGroup(classId); @@ -159,7 +161,7 @@ void UAVGadgetInstanceManager::readConfigs_1_1_0(QSettings *qs) { UAVConfigInfo configInfo; - foreach (QString classId, m_classIds.keys()) + foreach (QString classId, m_classIdNameMap.keys()) { IUAVGadgetFactory *f = factory(classId); qs->beginGroup(classId); @@ -242,7 +244,8 @@ void UAVGadgetInstanceManager::createOptionsPages() IUAVGadgetFactory *f = factory(config->classId()); IOptionsPage *p = f->createOptionsPage(config); if (p) { - IOptionsPage *page = new UAVGadgetOptionsPageDecorator(p, config); + IOptionsPage *page = new UAVGadgetOptionsPageDecorator(p, config, f->isSingleConfigurationGadget()); + page->setIcon(f->icon()); m_optionsPages.append(page); m_pm->addObject(page); } @@ -334,6 +337,7 @@ void UAVGadgetInstanceManager::cloneConfiguration(IUAVGadgetConfiguration *conf IUAVGadgetFactory *f = factory(config->classId()); IOptionsPage *p = f->createOptionsPage(config); IOptionsPage *page = new UAVGadgetOptionsPageDecorator(p, config); + page->setIcon(f->icon()); m_provisionalConfigs.append(config); m_provisionalOptionsPages.append(page); m_settingsDialog->insertPage(page); @@ -452,7 +456,12 @@ QStringList UAVGadgetInstanceManager::configurationNames(QString classId) const QString UAVGadgetInstanceManager::gadgetName(QString classId) const { - return m_classIds.value(classId); + return m_classIdNameMap.value(classId); +} + +QIcon UAVGadgetInstanceManager::gadgetIcon(QString classId) const +{ + return m_classIdIconMap.value(classId); } IUAVGadgetFactory *UAVGadgetInstanceManager::factory(QString classId) const diff --git a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.h b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.h index 1b8f574ee..fab30f284 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.h +++ b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.h @@ -32,6 +32,7 @@ #include #include #include +#include #include "core_global.h" #include "uavconfiginfo.h" @@ -68,9 +69,10 @@ public: void cloneConfiguration(IUAVGadgetConfiguration *config); void applyChanges(IUAVGadgetConfiguration *config); void configurationNameEdited(QString text, bool hasText = true); - QStringList classIds() const { return m_classIds.keys(); } + QStringList classIds() const { return m_classIdNameMap.keys(); } QStringList configurationNames(QString classId) const; QString gadgetName(QString classId) const; + QIcon gadgetIcon(QString classId) const; signals: void configurationChanged(IUAVGadgetConfiguration* config); @@ -91,7 +93,8 @@ private: QList m_factories; QList m_configurations; QList m_optionsPages; - QMap m_classIds; + QMap m_classIdNameMap; + QMap m_classIdIconMap; QMap m_takenNames; QList m_provisionalConfigs; QList m_provisionalDeletes; diff --git a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.cpp b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.cpp index a86b52d17..13b2b3062 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.cpp +++ b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.cpp @@ -91,6 +91,7 @@ UAVGadgetView::UAVGadgetView(Core::UAVGadgetManager *uavGadgetManager, IUAVGadge m_defaultIndex = 0; startFromOne = true; m_uavGadgetList->insertItem(0, im->gadgetName(classId), classId); + m_uavGadgetList->setItemIcon(0, im->gadgetIcon(classId)); m_uavGadgetList->insertSeparator(1); } else { @@ -101,6 +102,7 @@ UAVGadgetView::UAVGadgetView(Core::UAVGadgetManager *uavGadgetManager, IUAVGadge break; } m_uavGadgetList->insertItem(i, im->gadgetName(classId), classId); + m_uavGadgetList->setItemIcon(i, im->gadgetIcon(classId)); } ++index; } diff --git a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetoptionspagedecorator.cpp b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetoptionspagedecorator.cpp index d5fc1b054..f95f7e4c1 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetoptionspagedecorator.cpp +++ b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetoptionspagedecorator.cpp @@ -34,10 +34,12 @@ using namespace Core; -UAVGadgetOptionsPageDecorator::UAVGadgetOptionsPageDecorator(IOptionsPage *page, IUAVGadgetConfiguration *config, QObject *parent) : +UAVGadgetOptionsPageDecorator::UAVGadgetOptionsPageDecorator(IOptionsPage *page, IUAVGadgetConfiguration *config, + bool isSingleConfigurationGadget, QObject *parent) : Core::IOptionsPage(parent), m_optionsPage(page), m_config(config), + m_isSingleConfigurationGadget(isSingleConfigurationGadget), m_id(config->name()), m_category(config->classId()) { @@ -65,6 +67,11 @@ QWidget *UAVGadgetOptionsPageDecorator::createPage(QWidget *parent) wi->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); m_page->verticalLayout_4->addWidget(wi); + // For some gadgets it might not make sense to have multiple configurations + if (m_isSingleConfigurationGadget) { + m_page->configurationBox->hide(); + } + connect(m_page->cloneButton, SIGNAL(clicked()), this, SLOT(cloneConfiguration())); connect(m_page->deleteButton, SIGNAL(clicked()), this, SLOT(deleteConfiguration())); connect(m_page->nameLineEdit, SIGNAL(textEdited(QString)), this, SLOT(textEdited(QString))); diff --git a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetoptionspagedecorator.h b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetoptionspagedecorator.h index 919a8c510..14ec5bf39 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetoptionspagedecorator.h +++ b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetoptionspagedecorator.h @@ -43,7 +43,7 @@ class CORE_EXPORT UAVGadgetOptionsPageDecorator : public Core::IOptionsPage { Q_OBJECT public: - explicit UAVGadgetOptionsPageDecorator(IOptionsPage *page, IUAVGadgetConfiguration *config, QObject *parent = 0); + explicit UAVGadgetOptionsPageDecorator(IOptionsPage *page, IUAVGadgetConfiguration *config, bool isSingleConfigurationGadget = false, QObject *parent = 0); QString id() const { return m_id; } QString trName() const { return m_id; } @@ -66,6 +66,7 @@ private slots: private: IOptionsPage *m_optionsPage; IUAVGadgetConfiguration *m_config; + bool m_isSingleConfigurationGadget; UAVGadgetInstanceManager *m_instanceManager; QString m_id; QString m_category; diff --git a/ground/openpilotgcs/src/plugins/dial/dialgadgetfactory.cpp b/ground/openpilotgcs/src/plugins/dial/dialgadgetfactory.cpp index c267b4ee3..88cb6a024 100644 --- a/ground/openpilotgcs/src/plugins/dial/dialgadgetfactory.cpp +++ b/ground/openpilotgcs/src/plugins/dial/dialgadgetfactory.cpp @@ -34,7 +34,7 @@ DialGadgetFactory::DialGadgetFactory(QObject *parent) : IUAVGadgetFactory(QString("DialGadget"), - tr("Analog Dial Gadget"), + tr("Analog Dial"), parent) { } diff --git a/ground/openpilotgcs/src/plugins/gpsdisplay/gpsdisplaygadgetfactory.cpp b/ground/openpilotgcs/src/plugins/gpsdisplay/gpsdisplaygadgetfactory.cpp index 673891a16..e87290cba 100644 --- a/ground/openpilotgcs/src/plugins/gpsdisplay/gpsdisplaygadgetfactory.cpp +++ b/ground/openpilotgcs/src/plugins/gpsdisplay/gpsdisplaygadgetfactory.cpp @@ -33,7 +33,7 @@ GpsDisplayGadgetFactory::GpsDisplayGadgetFactory(QObject *parent) : IUAVGadgetFactory(QString("GpsDisplayGadget"), - tr("GPS Display Gadget"), + tr("GPS Display"), parent) { } diff --git a/ground/openpilotgcs/src/plugins/importexport/importexport.pro b/ground/openpilotgcs/src/plugins/importexport/importexport.pro index e3ae374a9..0d5d2778d 100644 --- a/ground/openpilotgcs/src/plugins/importexport/importexport.pro +++ b/ground/openpilotgcs/src/plugins/importexport/importexport.pro @@ -6,16 +6,14 @@ include(../../openpilotgcsplugin.pri) include(importexport_dependencies.pri) HEADERS += importexportplugin.h \ importexportgadgetwidget.h \ - importexportdialog.h \ - xmlconfig.h + importexportdialog.h HEADERS += importexportgadget.h HEADERS += importexportgadgetfactory.h HEADERS += importexportgadgetconfiguration.h HEADERS += importexportgadgetoptionspage.h SOURCES += importexportplugin.cpp \ importexportgadgetwidget.cpp \ - importexportdialog.cpp \ - xmlconfig.cpp + importexportdialog.cpp SOURCES += importexportgadget.cpp SOURCES += importexportgadgetfactory.cpp SOURCES += importexportgadgetconfiguration.cpp diff --git a/ground/openpilotgcs/src/plugins/importexport/importexportgadgetwidget.cpp b/ground/openpilotgcs/src/plugins/importexport/importexportgadgetwidget.cpp index da8a284af..eda567bde 100644 --- a/ground/openpilotgcs/src/plugins/importexport/importexportgadgetwidget.cpp +++ b/ground/openpilotgcs/src/plugins/importexport/importexportgadgetwidget.cpp @@ -28,7 +28,7 @@ */ #include "importexportgadgetwidget.h" #include "ui_importexportgadgetwidget.h" -#include "xmlconfig.h" +#include "utils/xmlconfig.h" #include "coreplugin/uavgadgetinstancemanager.h" #include "coreplugin/icore.h" #include diff --git a/ground/openpilotgcs/src/plugins/lineardial/lineardialgadgetfactory.cpp b/ground/openpilotgcs/src/plugins/lineardial/lineardialgadgetfactory.cpp index 33f6e0421..9e79256d3 100644 --- a/ground/openpilotgcs/src/plugins/lineardial/lineardialgadgetfactory.cpp +++ b/ground/openpilotgcs/src/plugins/lineardial/lineardialgadgetfactory.cpp @@ -33,7 +33,7 @@ LineardialGadgetFactory::LineardialGadgetFactory(QObject *parent) : IUAVGadgetFactory(QString("LineardialGadget"), - tr("Bargraph Dial Gadget"), + tr("Bargraph Dial"), parent) { } diff --git a/ground/openpilotgcs/src/plugins/modelview/modelviewgadgetfactory.cpp b/ground/openpilotgcs/src/plugins/modelview/modelviewgadgetfactory.cpp index a87bbbe75..090c6cc70 100644 --- a/ground/openpilotgcs/src/plugins/modelview/modelviewgadgetfactory.cpp +++ b/ground/openpilotgcs/src/plugins/modelview/modelviewgadgetfactory.cpp @@ -33,7 +33,7 @@ #include ModelViewGadgetFactory::ModelViewGadgetFactory(QObject *parent) : - IUAVGadgetFactory(QString("ModelViewGadget"), tr("ModelView Gadget"), parent) + IUAVGadgetFactory(QString("ModelViewGadget"), tr("ModelView"), parent) { } diff --git a/ground/openpilotgcs/src/plugins/opmap/opmapgadgetfactory.cpp b/ground/openpilotgcs/src/plugins/opmap/opmapgadgetfactory.cpp index fa60d10f0..5a3908c89 100644 --- a/ground/openpilotgcs/src/plugins/opmap/opmapgadgetfactory.cpp +++ b/ground/openpilotgcs/src/plugins/opmap/opmapgadgetfactory.cpp @@ -32,7 +32,7 @@ #include OPMapGadgetFactory::OPMapGadgetFactory(QObject *parent) : - IUAVGadgetFactory(QString("OPMapGadget"), tr("OPMap Gadget"), parent) + IUAVGadgetFactory(QString("OPMapGadget"), tr("OPMap"), parent) { } diff --git a/ground/openpilotgcs/src/plugins/pfd/pfdgadgetfactory.cpp b/ground/openpilotgcs/src/plugins/pfd/pfdgadgetfactory.cpp index 82932cf62..b76b87361 100644 --- a/ground/openpilotgcs/src/plugins/pfd/pfdgadgetfactory.cpp +++ b/ground/openpilotgcs/src/plugins/pfd/pfdgadgetfactory.cpp @@ -33,7 +33,7 @@ PFDGadgetFactory::PFDGadgetFactory(QObject *parent) : IUAVGadgetFactory(QString("PFDGadget"), - tr("Primary Flight Display Gadget"), + tr("Primary Flight Display"), parent) { } diff --git a/ground/openpilotgcs/src/plugins/pipxtreme/pipxtremegadgetfactory.cpp b/ground/openpilotgcs/src/plugins/pipxtreme/pipxtremegadgetfactory.cpp index 42ce2ec91..4574913d5 100644 --- a/ground/openpilotgcs/src/plugins/pipxtreme/pipxtremegadgetfactory.cpp +++ b/ground/openpilotgcs/src/plugins/pipxtreme/pipxtremegadgetfactory.cpp @@ -31,7 +31,7 @@ #include PipXtremeGadgetFactory::PipXtremeGadgetFactory(QObject *parent) : - IUAVGadgetFactory(QString("PipXtreme"), tr("PipXtreme Gadget"), parent) + IUAVGadgetFactory(QString("PipXtreme"), tr("PipXtreme"), parent) { } @@ -49,8 +49,3 @@ IUAVGadgetConfiguration * PipXtremeGadgetFactory::createConfiguration(QSettings { return new PipXtremeGadgetConfiguration(QString("PipXtreme"), qSettings); } - -IOptionsPage * PipXtremeGadgetFactory::createOptionsPage(IUAVGadgetConfiguration *config) -{ - return new PipXtremeGadgetOptionsPage(qobject_cast(config)); -} diff --git a/ground/openpilotgcs/src/plugins/pipxtreme/pipxtremegadgetfactory.h b/ground/openpilotgcs/src/plugins/pipxtreme/pipxtremegadgetfactory.h index d6d2bf736..8bd48f46b 100644 --- a/ground/openpilotgcs/src/plugins/pipxtreme/pipxtremegadgetfactory.h +++ b/ground/openpilotgcs/src/plugins/pipxtreme/pipxtremegadgetfactory.h @@ -45,7 +45,6 @@ public: Core::IUAVGadget * createGadget(QWidget *parent); IUAVGadgetConfiguration * createConfiguration(QSettings *qSettings); - IOptionsPage * createOptionsPage(IUAVGadgetConfiguration *config); }; #endif diff --git a/ground/openpilotgcs/src/plugins/scope/scopegadgetfactory.cpp b/ground/openpilotgcs/src/plugins/scope/scopegadgetfactory.cpp index 1c62c1f57..adbdcdd0d 100644 --- a/ground/openpilotgcs/src/plugins/scope/scopegadgetfactory.cpp +++ b/ground/openpilotgcs/src/plugins/scope/scopegadgetfactory.cpp @@ -33,7 +33,7 @@ ScopeGadgetFactory::ScopeGadgetFactory(QObject *parent) : IUAVGadgetFactory(QString("ScopeGadget"), - tr("Scope Gadget"), + tr("Scope"), parent) { } diff --git a/ground/openpilotgcs/src/plugins/systemhealth/systemhealthgadgetfactory.cpp b/ground/openpilotgcs/src/plugins/systemhealth/systemhealthgadgetfactory.cpp index 80abb1be7..41e068c17 100644 --- a/ground/openpilotgcs/src/plugins/systemhealth/systemhealthgadgetfactory.cpp +++ b/ground/openpilotgcs/src/plugins/systemhealth/systemhealthgadgetfactory.cpp @@ -33,7 +33,7 @@ SystemHealthGadgetFactory::SystemHealthGadgetFactory(QObject *parent) : IUAVGadgetFactory(QString("SystemHealthGadget"), - tr("System Health Gadget"), + tr("System Health"), parent) { } diff --git a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetfactory.cpp b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetfactory.cpp index 4099b936b..692985e5c 100755 --- a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetfactory.cpp +++ b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetfactory.cpp @@ -33,7 +33,7 @@ #include UploaderGadgetFactory::UploaderGadgetFactory(QObject *parent) : - IUAVGadgetFactory(QString("Uploader"), tr("Uploader Gadget"), parent) + IUAVGadgetFactory(QString("Uploader"), tr("Uploader"), parent) { } @@ -52,8 +52,3 @@ IUAVGadgetConfiguration *UploaderGadgetFactory::createConfiguration(QSettings* q return new UploaderGadgetConfiguration(QString("Uploader"), qSettings); } -IOptionsPage *UploaderGadgetFactory::createOptionsPage(IUAVGadgetConfiguration *config) -{ - return new UploaderGadgetOptionsPage(qobject_cast(config)); -} - diff --git a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetfactory.h b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetfactory.h index fb44be6cc..c836287b1 100755 --- a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetfactory.h +++ b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetfactory.h @@ -46,7 +46,6 @@ public: Core::IUAVGadget *createGadget(QWidget *parent); IUAVGadgetConfiguration *createConfiguration(QSettings* qSettings); - IOptionsPage *createOptionsPage(IUAVGadgetConfiguration *config); }; #endif // UPLOADERGADGETFACTORY_H diff --git a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp index 2943bcdfd..5a4b350b2 100755 --- a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp +++ b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp @@ -33,7 +33,6 @@ UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent) m_config = new Ui_UploaderWidget(); m_config->setupUi(this); currentStep = IAP_STATE_READY; - rescueStep = RESCUE_STEP0; resetOnly=false; dfu = NULL; @@ -393,89 +392,93 @@ void UploaderGadgetWidget::systemBoot() void UploaderGadgetWidget::systemRescue() { Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); - switch (rescueStep) { - case RESCUE_STEP0: { - cm->disconnectDevice(); - // stop the polling thread: otherwise it will mess up DFU - cm->suspendPolling(); - // Delete all previous tabs: - while (m_config->systemElements->count()) { - QWidget *qw = m_config->systemElements->widget(0); - m_config->systemElements->removeTab(0); - delete qw; - } - // Existing DFU objects will have a handle over USB and will - // disturb everything for the rescue process: - if (dfu) { - delete dfu; - dfu = NULL; - } - // Avoid dumb users pressing Rescue twice. It can happen. - m_config->rescueButton->setEnabled(false); - - // Now we're good to go: - clearLog(); - log("**********************************************************"); - log("** Follow those instructions to attempt a system rescue **"); - log("**********************************************************"); - log("You will be prompted to first connect USB, then system power"); - log ("Connect USB in 2 seconds..."); - rescueStep = RESCUE_STEP1; - QTimer::singleShot(1000, this, SLOT(systemRescue())); + cm->disconnectDevice(); + // stop the polling thread: otherwise it will mess up DFU + cm->suspendPolling(); + // Delete all previous tabs: + while (m_config->systemElements->count()) { + QWidget *qw = m_config->systemElements->widget(0); + m_config->systemElements->removeTab(0); + delete qw; } - break; - case RESCUE_STEP1: - rescueStep = RESCUE_STEP2; - log (" ...1..."); - QTimer::singleShot(1000, this, SLOT(systemRescue())); - break; - case RESCUE_STEP2: - rescueStep = RESCUE_STEP3; - log(" ...Now!"); - QTimer::singleShot(1000, this, SLOT(systemRescue())); - break; - case RESCUE_STEP3: - log("... Detecting First Board..."); - repaint(); - dfu = new DFUObject(DFU_DEBUG, false, QString()); - dfu->AbortOperation(); - if(!dfu->enterDFU(0)) + // Existing DFU objects will have a handle over USB and will + // disturb everything for the rescue process: + if (dfu) { + delete dfu; + dfu = NULL; + } + // Avoid dumb users pressing Rescue twice. It can happen. + m_config->rescueButton->setEnabled(false); + + // Now we're good to go: + clearLog(); + log("**********************************************************"); + log("** Follow those instructions to attempt a system rescue **"); + log("**********************************************************"); + log("You will be prompted to first connect USB, then system power"); + if(USBMonitor::instance()->availableDevices(0x20a0,-1,-1,-1).length()>0) + { + if(QMessageBox::warning(this,tr("OpenPilot Uploader"),tr("Please disconnect all openpilot boards"),QMessageBox::Ok,QMessageBox::Cancel)==QMessageBox::Cancel) { - rescueStep = RESCUE_STEP0; - log("Could not enter DFU mode."); - delete dfu; - dfu = NULL; - cm->resumePolling(); m_config->rescueButton->setEnabled(true); return; } - if(!dfu->findDevices() || (dfu->numberOfDevices != 1)) - { - rescueStep = RESCUE_STEP0; - log("Could not detect a board, aborting!"); - delete dfu; - dfu = NULL; - cm->resumePolling(); - m_config->rescueButton->setEnabled(true); - return; - } - rescueStep = RESCUE_POWER1; - log("Connect Power in 2 second..."); - log("(not required on CopterControl)"); - QTimer::singleShot(1000, this, SLOT(systemRescue())); - break; - case RESCUE_POWER1: - rescueStep = RESCUE_POWER2; - log(" ...1..."); - QTimer::singleShot(1000, this, SLOT(systemRescue())); - break; - case RESCUE_POWER2: - log("... NOW!\n***\nWaiting..."); - rescueStep = RESCUE_DETECT; - QTimer::singleShot(5000, this, SLOT(systemRescue())); - break; - case RESCUE_DETECT: - rescueStep = RESCUE_STEP0; + } + // Now we're good to go: + clearLog(); + log("**********************************************************"); + log("** Follow those instructions to attempt a system rescue **"); + log("**********************************************************"); + log("You will be prompted to first connect USB, then system power"); + pd = new QProgressDialog(tr("Please connect the board (USB only!)"), tr("Cancel"), 0, 20); + QProgressBar * bar=new QProgressBar(pd); + bar->setFormat("Timeout"); + pd->setBar(bar); + pd->setMinimumDuration(0); + pd->setRange(0,20); + connect(pd, SIGNAL(canceled()), this, SLOT(cancel())); + t = new QTimer(this); + connect(t, SIGNAL(timeout()), this, SLOT(perform())); + t->start(1000); + connect(USBMonitor::instance(), SIGNAL(deviceDiscovered(USBPortInfo)),&q, SLOT(quit())); + q.exec(); + if(!t->isActive()) + { + pd->close(); + t->stop(); + QMessageBox::warning(this,tr("Openpilot Uploader"),tr("No board connection was detected!")); + m_config->rescueButton->setEnabled(true); + return; + } + pd->close(); + t->stop(); + log("... Detecting First Board..."); + repaint(); + dfu = new DFUObject(DFU_DEBUG, false, QString()); + dfu->AbortOperation(); + if(!dfu->enterDFU(0)) + { + log("Could not enter DFU mode."); + delete dfu; + dfu = NULL; + cm->resumePolling(); + m_config->rescueButton->setEnabled(true); + return; + } + if(!dfu->findDevices() || (dfu->numberOfDevices != 1)) + { + log("Could not detect a board, aborting!"); + delete dfu; + dfu = NULL; + cm->resumePolling(); + m_config->rescueButton->setEnabled(true); + return; + } + if(QMessageBox::question(this,tr("OpenPilot Uploader"),tr("If you want to search for other boards connect power now and press Yes"),QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes) + { + log("\nWaiting..."); + QTimer::singleShot(3000, &q, SLOT(quit())); + q.exec(); log("Detecting second board..."); repaint(); if(!dfu->findDevices()) @@ -489,28 +492,42 @@ void UploaderGadgetWidget::systemRescue() m_config->rescueButton->setEnabled(true); return; } - log(QString("Found ") + QString::number(dfu->numberOfDevices) + QString(" device(s).")); - if (dfu->numberOfDevices > 5) { - log("Inconsistent number of devices, aborting!"); - delete dfu; - dfu = NULL; - cm->resumePolling(); - m_config->rescueButton->setEnabled(true); - return; - } - for(int i=0;inumberOfDevices;i++) { - deviceWidget* dw = new deviceWidget(this); - dw->setDeviceID(i); - dw->setDfu(dfu); - dw->populate(); - m_config->systemElements->addTab(dw, QString("Device") + QString::number(i)); - } - m_config->haltButton->setEnabled(false); - m_config->resetButton->setEnabled(false); - m_config->bootButton->setEnabled(true); - m_config->rescueButton->setEnabled(false); - currentStep = IAP_STATE_BOOTLOADER; // So that we can boot from the GUI afterwards. } + log(QString("Found ") + QString::number(dfu->numberOfDevices) + QString(" device(s).")); + if (dfu->numberOfDevices > 5) { + log("Inconsistent number of devices, aborting!"); + delete dfu; + dfu = NULL; + cm->resumePolling(); + m_config->rescueButton->setEnabled(true); + return; + } + for(int i=0;inumberOfDevices;i++) { + deviceWidget* dw = new deviceWidget(this); + dw->setDeviceID(i); + dw->setDfu(dfu); + dw->populate(); + m_config->systemElements->addTab(dw, QString("Device") + QString::number(i)); + } + m_config->haltButton->setEnabled(false); + m_config->resetButton->setEnabled(false); + m_config->bootButton->setEnabled(true); + m_config->rescueButton->setEnabled(false); + currentStep = IAP_STATE_BOOTLOADER; // So that we can boot from the GUI afterwards. +} +void UploaderGadgetWidget::perform() +{ + if(pd->value()==19) + { + t->stop(); + q.exit(); + } + pd->setValue(pd->value()+1); +} +void UploaderGadgetWidget::cancel() +{ + t->stop(); + q.exit(); } /** @@ -538,6 +555,11 @@ UploaderGadgetWidget::~UploaderGadgetWidget() m_config->systemElements->removeTab(0); delete qw; } + if (pd) + delete pd; + if (t) + delete t; + } diff --git a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.h b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.h index 7c7bae19e..b629ad605 100755 --- a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.h +++ b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.h @@ -53,6 +53,7 @@ #include #include +#include using namespace OP_DFU; @@ -64,7 +65,6 @@ public: UploaderGadgetWidget(QWidget *parent = 0); ~UploaderGadgetWidget(); typedef enum { IAP_STATE_READY, IAP_STATE_STEP_1, IAP_STATE_STEP_2, IAP_STEP_RESET, IAP_STATE_BOOTLOADER} IAPStep; - typedef enum { RESCUE_STEP0, RESCUE_STEP1, RESCUE_STEP2, RESCUE_STEP3, RESCUE_POWER1, RESCUE_POWER2, RESCUE_DETECT } RescueStep; void log(QString str); public slots: @@ -75,13 +75,13 @@ private: Ui_UploaderWidget *m_config; DFUObject *dfu; IAPStep currentStep; - RescueStep rescueStep; bool resetOnly; void clearLog(); QString getPortDevice(const QString &friendName); - + QProgressDialog* pd; + QTimer* t; QLineEdit* openFileNameLE; - + QEventLoop q; private slots: void error(QString errorString,int errorNumber); void info(QString infoString,int infoNumber); @@ -90,6 +90,8 @@ private slots: void systemBoot(); void systemRescue(); void getSerialPorts(); + void perform(); + void cancel(); };