diff --git a/ground/openpilotgcs/src/plugins/config/airframe_fixedwing.ui b/ground/openpilotgcs/src/plugins/config/airframe_fixedwing.ui index 1b42f042d..176b5daca 100644 --- a/ground/openpilotgcs/src/plugins/config/airframe_fixedwing.ui +++ b/ground/openpilotgcs/src/plugins/config/airframe_fixedwing.ui @@ -37,6 +37,14 @@ Airplane type: + + + + 0 + 0 + + + diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp index 1a667fa5e..07ba0a4ba 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp @@ -36,10 +36,13 @@ #include #include #include +#include #include #include #include +const QString ConfigFixedWingWidget::CHANNELBOXNAME = QString("fixedWingChannelBox"); + QStringList ConfigFixedWingWidget::getChannelDescriptions() { // init a channel_numelem list of channel desc defaults @@ -51,27 +54,28 @@ QStringList ConfigFixedWingWidget::getChannelDescriptions() // get the gui config data GUIConfigDataUnion configData = getConfigData(); + fixedGUISettingsStruct fixed = configData.fixedwing; - if (configData.fixedwing.FixedWingPitch1 > 0) { - channelDesc[configData.fixedwing.FixedWingPitch1 - 1] = QString("FixedWingPitch1"); + if (fixed.FixedWingThrottle > 0 && fixed.FixedWingThrottle <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixed.FixedWingThrottle - 1] = QString("WingThrottle"); } - if (configData.fixedwing.FixedWingPitch2 > 0) { - channelDesc[configData.fixedwing.FixedWingPitch2 - 1] = QString("FixedWingPitch2"); + if (fixed.FixedWingPitch1 > 0 && fixed.FixedWingPitch1 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixed.FixedWingPitch1 - 1] = QString("FixedWingPitch1"); } - if (configData.fixedwing.FixedWingRoll1 > 0) { - channelDesc[configData.fixedwing.FixedWingRoll1 - 1] = QString("FixedWingRoll1"); + if (fixed.FixedWingPitch2 > 0 && fixed.FixedWingPitch2 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixed.FixedWingPitch2 - 1] = QString("FixedWingPitch2"); } - if (configData.fixedwing.FixedWingRoll2 > 0) { - channelDesc[configData.fixedwing.FixedWingRoll2 - 1] = QString("FixedWingRoll2"); + if (fixed.FixedWingRoll1 > 0 && fixed.FixedWingRoll1 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixed.FixedWingRoll1 - 1] = QString("FixedWingRoll1"); } - if (configData.fixedwing.FixedWingYaw1 > 0) { - channelDesc[configData.fixedwing.FixedWingYaw1 - 1] = QString("FixedWingYaw1"); + if (fixed.FixedWingRoll2 > 0 && fixed.FixedWingRoll2 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixed.FixedWingRoll2 - 1] = QString("FixedWingRoll2"); } - if (configData.fixedwing.FixedWingYaw2 > 0) { - channelDesc[configData.fixedwing.FixedWingYaw2 - 1] = QString("FixedWingYaw2"); + if (fixed.FixedWingYaw1 > 0 && fixed.FixedWingYaw1 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixed.FixedWingYaw1 - 1] = QString("FixedWingYaw1"); } - if (configData.fixedwing.FixedWingThrottle > 0) { - channelDesc[configData.fixedwing.FixedWingThrottle - 1] = QString("FixedWingThrottle"); + if (fixed.FixedWingYaw2 > 0 && fixed.FixedWingYaw2 <= ConfigFixedWingWidget::CHANNEL_NUMELEM) { + channelDesc[fixed.FixedWingYaw2 - 1] = QString("FixedWingYaw2"); } return channelDesc; } @@ -84,13 +88,16 @@ ConfigFixedWingWidget::ConfigFixedWingWidget(QWidget *parent) : populateChannelComboBoxes(); QStringList fixedWingTypes; - fixedWingTypes << "Elevator aileron rudder" << "Elevon" << "Vtail"; + fixedWingTypes << "Elevator aileron rudder" << "Vtail"; m_aircraft->fixedWingType->addItems(fixedWingTypes); // Set default model to "Elevator aileron rudder" - connect(m_aircraft->fixedWingType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupUI(QString))); m_aircraft->fixedWingType->setCurrentIndex(m_aircraft->fixedWingType->findText("Elevator aileron rudder")); - setupUI(m_aircraft->fixedWingType->currentText()); + + // setupUI(m_aircraft->fixedWingType->currentText()); + + connect(m_aircraft->fixedWingType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupUI(QString))); + updateEnableControls(); } ConfigFixedWingWidget::~ConfigFixedWingWidget() @@ -98,14 +105,24 @@ ConfigFixedWingWidget::~ConfigFixedWingWidget() delete m_aircraft; } -/** - Virtual function to setup the UI - */ void ConfigFixedWingWidget::setupUI(QString frameType) { Q_ASSERT(m_aircraft); + Q_ASSERT(plane); + + // This had to be moved from ConfigFixedWingWidget() here since m_aircraft->fixedWingType->currentText() + // did not seem to work properly to choose alternate .svg files. + m_aircraft->planeShape->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_aircraft->planeShape->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + QSvgRenderer *renderer = new QSvgRenderer(); + renderer->load(QString(":/configgadget/images/fixedwing-shapes.svg")); + plane = new QGraphicsSvgItem(); + plane->setSharedRenderer(renderer); + + qDebug() << "Current Aircraft type: \n" << m_aircraft->fixedWingType->currentText(); if (frameType == "FixedWing" || frameType == "Elevator aileron rudder") { + plane->setElementId("aileron"); setComboCurrentIndex(m_aircraft->fixedWingType, m_aircraft->fixedWingType->findText("Elevator aileron rudder")); m_aircraft->fwRudder1ChannelBox->setEnabled(true); m_aircraft->fwRudder2ChannelBox->setEnabled(true); @@ -121,23 +138,8 @@ void ConfigFixedWingWidget::setupUI(QString frameType) m_aircraft->elevonSlider1->setEnabled(false); m_aircraft->elevonSlider2->setEnabled(false); - } else if (frameType == "FixedWingElevon" || frameType == "Elevon") { - setComboCurrentIndex(m_aircraft->fixedWingType, m_aircraft->fixedWingType->findText("Elevon")); - m_aircraft->fwAileron1Label->setText("Elevon 1"); - m_aircraft->fwAileron2Label->setText("Elevon 2"); - m_aircraft->fwElevator1ChannelBox->setEnabled(false); - m_aircraft->fwElevator2ChannelBox->setEnabled(false); - m_aircraft->fwRudder1ChannelBox->setEnabled(true); - m_aircraft->fwRudder2ChannelBox->setEnabled(true); - - m_aircraft->fwElevator1Label->setText("Elevator 1"); - m_aircraft->fwElevator2Label->setText("Elevator 2"); - m_aircraft->elevonLabel1->setText("Roll"); - m_aircraft->elevonLabel2->setText("Pitch"); - - m_aircraft->elevonSlider1->setEnabled(true); - m_aircraft->elevonSlider2->setEnabled(true); } else if (frameType == "FixedWingVtail" || frameType == "Vtail") { + plane->setElementId("vtail"); setComboCurrentIndex(m_aircraft->fixedWingType, m_aircraft->fixedWingType->findText("Vtail")); m_aircraft->fwRudder1ChannelBox->setEnabled(false); m_aircraft->fwRudder2ChannelBox->setEnabled(false); @@ -156,6 +158,35 @@ void ConfigFixedWingWidget::setupUI(QString frameType) m_aircraft->elevonSlider1->setEnabled(true); m_aircraft->elevonSlider2->setEnabled(true); } + + QGraphicsScene *scene = new QGraphicsScene(); + scene->addItem(plane); + scene->setSceneRect(plane->boundingRect()); + m_aircraft->planeShape->setScene(scene); + + setupEnabledControls(frameType); + // Draw the appropriate airframe + updateAirframe(frameType); +} + +void ConfigFixedWingWidget::setupEnabledControls(QString frameType) +{ + + // disable all motor channel boxes + for (int i = 1; i <= 8; i++) { + // do it manually so we can turn off any error decorations + QComboBox *combobox = this->findChild("fixedWingChannelBox" + QString::number(i)); + if (combobox) { + combobox->setEnabled(false); + combobox->setItemData(0, 0, Qt::DecorationRole); + } + } + + if (frameType == "Vtail" || frameType == "vtail") { + enableComboBoxes(this, CHANNELBOXNAME, 3, true); + } else if (frameType == "aileron" || frameType == "Elevator aileron rudder") { + enableComboBoxes(this, CHANNELBOXNAME, 4, true); + } } void ConfigFixedWingWidget::registerWidgets(ConfigTaskWidget &parent) @@ -222,18 +253,9 @@ void ConfigFixedWingWidget::refreshWidgetsValues(QString frameType) setComboCurrentIndex(m_aircraft->fwRudder1ChannelBox, fixed.FixedWingYaw1); setComboCurrentIndex(m_aircraft->fwRudder2ChannelBox, fixed.FixedWingYaw2); - if (frameType == "FixedWingElevon") { - // If the airframe is elevon, restore the slider setting + if (frameType == "FixedWingVtail") { + // If the airframe is vtail, restore the slider setting // Find the channel number for Elevon1 (FixedWingRoll1) - int channel = m_aircraft->fwAileron1ChannelBox->currentIndex() - 1; - if (channel > -1) { - // If for some reason the actuators were incoherent, we might fail here, hence the check. - m_aircraft->elevonSlider1->setValue( - getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL) * 100); - m_aircraft->elevonSlider2->setValue( - getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH) * 100); - } - } else if (frameType == "FixedWingVtail") { int channel = m_aircraft->fwElevator1ChannelBox->currentIndex() - 1; if (channel > -1) { // If for some reason the actuators were incoherent, we might fail here, hence the check. @@ -243,41 +265,115 @@ void ConfigFixedWingWidget::refreshWidgetsValues(QString frameType) getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH) * 100); } } + + updateAirframe(frameType); } /** - Virtual function to update the UI widget objects + Helper function to update the UI widget objects */ QString ConfigFixedWingWidget::updateConfigObjectsFromWidgets() { - QString airframeType = "FixedWing"; - - // Save the curve (common to all Fixed wing frames) UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); - // Remove Feed Forward, it is pointless on a plane: - setMixerValue(mixer, "FeedForward", 0.0); - - // Set the throttle curve + // Curve is also common to all quads: setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->fixedWingThrottle->getCurve()); - // All airframe types must start with "FixedWing" + QString airframeType; + QList motor_servo_List; + if (m_aircraft->fixedWingType->currentText() == "Elevator aileron rudder") { airframeType = "FixedWing"; setupFrameFixedWing(airframeType); - } else if (m_aircraft->fixedWingType->currentText() == "Elevon") { - airframeType = "FixedWingElevon"; - setupFrameElevon(airframeType); - } else { // "Vtail" + + motor_servo_List << "FixedWingThrottle" << "FixedWingPitch1" << "FixedWingPitch2" << "FixedWingRoll1" << "FixedWingRoll2" << "FixedWingYaw1" << "FixedWingYaw2"; + setupMotors(motor_servo_List); + + GUIConfigDataUnion config = getConfigData(); + setConfigData(config); + + m_aircraft->fwStatusLabel->setText(tr("Configuration OK")); + + } + else if (m_aircraft->fixedWingType->currentText() == "vtail") { airframeType = "FixedWingVtail"; setupFrameVtail(airframeType); + + motor_servo_List << "FixedWingThrottle" << "FixedWingRoll1" << "FixedWingRoll2"; + setupMotors(motor_servo_List); + + GUIConfigDataUnion config = getConfigData(); + setConfigData(config); + + // Vtail Layout: + // pitch roll yaw + double mixerMatrix[8][3] = { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 } + }; + setupFixedWingMixer(mixerMatrix); + + m_aircraft->fwStatusLabel->setText(tr("Configuration OK")); + } + + // Remove Feed Forward, it is pointless on a plane: + setMixerValue(mixer, "FeedForward", 0.0); return airframeType; } +void ConfigFixedWingWidget::setupMotors(QList motorList) +{ + QList mmList; + mmList << m_aircraft->fwEngineChannelBox << m_aircraft->fwAileron1ChannelBox + << m_aircraft->fwAileron2ChannelBox << m_aircraft->fwElevator1ChannelBox + << m_aircraft->fwElevator2ChannelBox << m_aircraft->fwRudder1ChannelBox + << m_aircraft->fwRudder2ChannelBox; + + GUIConfigDataUnion configData = getConfigData(); + resetActuators(&configData); + + foreach(QString motor, motorList) { + int index = mmList.takeFirst()->currentIndex(); + + if (motor == QString("FixedWingThrottle")) { + configData.fixedwing.FixedWingThrottle = index; + } else if (motor == QString("FixedWingPitch1")) { + configData.fixedwing.FixedWingPitch1 = index; + } else if (motor == QString("FixedWingPitch2")) { + configData.fixedwing.FixedWingPitch2 = index; + } else if (motor == QString("FixedWingRoll1")) { + configData.fixedwing.FixedWingRoll1 = index; + } else if (motor == QString("FixedWingRoll2")) { + configData.fixedwing.FixedWingRoll2 = index; + } else if (motor == QString("FixedWingYaw1")) { + configData.fixedwing.FixedWingYaw1 = index; + } else if (motor == QString("FixedWingYaw2")) { + configData.fixedwing.FixedWingYaw1 = index; + } + } + setConfigData(configData); +} + +void ConfigFixedWingWidget::updateAirframe(QString frameType) +{ + qDebug() << "ConfigFixedWingWidget::updateAirframe - frame type" << frameType; + + // this is not doing anything right now + + m_aircraft->planeShape->setSceneRect(plane->boundingRect()); + m_aircraft->planeShape->fitInView(plane, Qt::KeepAspectRatio); +} + /** Setup Elevator/Aileron/Rudder airframe. @@ -302,6 +398,7 @@ bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType) config.fixedwing.FixedWingRoll1 = m_aircraft->fwAileron1ChannelBox->currentIndex(); config.fixedwing.FixedWingRoll2 = m_aircraft->fwAileron2ChannelBox->currentIndex(); config.fixedwing.FixedWingYaw1 = m_aircraft->fwRudder1ChannelBox->currentIndex(); + config.fixedwing.FixedWingYaw2 = m_aircraft->fwRudder2ChannelBox->currentIndex(); config.fixedwing.FixedWingThrottle = m_aircraft->fwEngineChannelBox->currentIndex(); setConfigData(config); @@ -353,76 +450,6 @@ bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType) return true; } -/** - Setup Elevon - */ -bool ConfigFixedWingWidget::setupFrameElevon(QString airframeType) -{ - // Check coherence: - // Show any config errors in GUI - if (throwConfigError(airframeType)) { - return false; - } - - GUIConfigDataUnion config = getConfigData(); - resetActuators(&config); - - config.fixedwing.FixedWingRoll1 = m_aircraft->fwAileron1ChannelBox->currentIndex(); - config.fixedwing.FixedWingRoll2 = m_aircraft->fwAileron2ChannelBox->currentIndex(); - config.fixedwing.FixedWingYaw1 = m_aircraft->fwRudder1ChannelBox->currentIndex(); - config.fixedwing.FixedWingYaw2 = m_aircraft->fwRudder2ChannelBox->currentIndex(); - config.fixedwing.FixedWingThrottle = m_aircraft->fwEngineChannelBox->currentIndex(); - - setConfigData(config); - - UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(mixer); - resetMotorAndServoMixers(mixer); - - // Save the curve: - // ... 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 - - double value; - - // motor - int channel = m_aircraft->fwEngineChannelBox->currentIndex() - 1; - setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_MOTOR); - setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); - - // rudders - channel = m_aircraft->fwRudder1ChannelBox->currentIndex() - 1; - setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); - setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127); - - channel = m_aircraft->fwRudder2ChannelBox->currentIndex() - 1; - setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); - setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127); - - // ailerons - channel = m_aircraft->fwAileron1ChannelBox->currentIndex() - 1; - if (channel > -1) { - setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); - value = (double)(m_aircraft->elevonSlider2->value() * 1.27); - setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, value); - value = (double)(m_aircraft->elevonSlider1->value() * 1.27); - setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, value); - - channel = m_aircraft->fwAileron2ChannelBox->currentIndex() - 1; - setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); - value = (double)(m_aircraft->elevonSlider2->value() * 1.27); - setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, value); - value = (double)(m_aircraft->elevonSlider1->value() * 1.27); - setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, -value); - } - - m_aircraft->fwStatusLabel->setText("Mixer generated"); - return true; -} - /** Setup VTail */ @@ -502,13 +529,39 @@ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType) return true; } -void ConfigFixedWingWidget::enableControls(bool enable) +/** + This function sets up the vtail fixed wing mixer values. + */ +bool ConfigFixedWingWidget::setupFixedWingMixer(double mixerFactors[8][3]) { - ConfigTaskWidget::enableControls(enable); + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - if (enable) { - setupUI(m_aircraft->fixedWingType->currentText()); + Q_ASSERT(mixer); + resetMotorAndServoMixers(mixer); + + // and enable only the relevant channels: +// double pFactor = (double)m_aircraft->fwPitchMixLevel->value() / 100.0; +// double rFactor = (double)m_aircraft->fwRollMixLevel->value() / 100.0; + //invertMotors = m_aircraft->MultirotorRevMixerCheckBox->isChecked(); +// double yFactor = (double)m_aircraft->fwYawMixLevel->value() / 100.0; + + QList mmList; + mmList << m_aircraft->fwEngineChannelBox << m_aircraft->fwAileron1ChannelBox + << m_aircraft->fwAileron2ChannelBox << m_aircraft->fwElevator1ChannelBox + << m_aircraft->fwElevator2ChannelBox << m_aircraft->fwRudder1ChannelBox + << m_aircraft->fwRudder2ChannelBox; + + for (int i = 0; i < 8; i++) { + if (mmList.at(i)->isEnabled()) { + int channel = mmList.at(i)->currentIndex() - 1; + if (channel > -1) { + qDebug() << "code needs to be written here!"; +// setupQuadMotor(channel, mixerFactors[i][0] * pFactor, rFactor * mixerFactors[i][1], +// yFactor * mixerFactors[i][2]); + } + } } + return true; } /** @@ -550,27 +603,6 @@ bool ConfigFixedWingWidget::throwConfigError(QString airframeType) m_aircraft->fwAileron1ChannelBox->setItemData(0, 0, Qt::DecorationRole); // Reset color palettes m_aircraft->fwRudder1ChannelBox->setItemData(0, 0, Qt::DecorationRole); // Reset color palettes } - } else if (airframeType == "FixedWingElevon") { - if (m_aircraft->fwEngineChannelBox->currentText() == "None") { - m_aircraft->fwEngineChannelBox->setItemData(0, pixmap, Qt::DecorationRole); // Set color palettes - error = true; - } else { - m_aircraft->fwEngineChannelBox->setItemData(0, 0, Qt::DecorationRole); // Reset color palettes - } - - if (m_aircraft->fwAileron1ChannelBox->currentText() == "None") { - m_aircraft->fwAileron1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); // Set color palettes - error = true; - } else { - m_aircraft->fwAileron1ChannelBox->setItemData(0, 0, Qt::DecorationRole); // Reset color palettes - } - - if (m_aircraft->fwAileron2ChannelBox->currentText() == "None") { - m_aircraft->fwAileron2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); // Set color palettes - error = true; - } else { - m_aircraft->fwAileron2ChannelBox->setItemData(0, 0, Qt::DecorationRole); // Reset color palettes - } } else if (airframeType == "FixedWingVtail") { if (m_aircraft->fwEngineChannelBox->currentText() == "None") { m_aircraft->fwEngineChannelBox->setItemData(0, pixmap, Qt::DecorationRole); // Set color palettes @@ -600,3 +632,34 @@ bool ConfigFixedWingWidget::throwConfigError(QString airframeType) return error; } + +/** + WHAT DOES THIS DO??? + */ +void ConfigFixedWingWidget::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->planeShape->fitInView(plane, Qt::KeepAspectRatio); +} + +/** + Resize the GUI contents when the user changes the window size + */ +void ConfigFixedWingWidget::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + m_aircraft->planeShape->fitInView(plane, Qt::KeepAspectRatio); +} + +void ConfigFixedWingWidget::enableControls(bool enable) +{ + ConfigTaskWidget::enableControls(enable); + + if (enable) { + setupEnabledControls(m_aircraft->fixedWingType->currentText()); + } +} + diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.h b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.h index f0b786379..56a386daf 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.h +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.h @@ -44,6 +44,7 @@ class ConfigFixedWingWidget : public VehicleConfig { Q_OBJECT public: + static const QString CHANNELBOXNAME; static QStringList getChannelDescriptions(); ConfigFixedWingWidget(QWidget *parent = 0); @@ -52,19 +53,25 @@ public: virtual void refreshWidgetsValues(QString frameType); virtual QString updateConfigObjectsFromWidgets(); +protected: + void showEvent(QShowEvent *event); + void resizeEvent(QResizeEvent *event); + void enableControls(bool enable); + private: Ui_FixedWingConfigWidget *m_aircraft; + QGraphicsSvgItem *plane; virtual void registerWidgets(ConfigTaskWidget &parent); virtual void resetActuators(GUIConfigDataUnion *configData); bool setupFrameFixedWing(QString airframeType); - bool setupFrameElevon(QString airframeType); bool setupFrameVtail(QString airframeType); + bool setupFixedWingMixer(double mixerFactors[8][3]); + void setupMotors(QList motorList); -protected: - void enableControls(bool enable); - + void updateAirframe(QString multiRotorType); + void setupEnabledControls(QString airframeType); private slots: virtual void setupUI(QString airframeType); virtual bool throwConfigError(QString airframeType); diff --git a/ground/openpilotgcs/src/plugins/config/configgadget.qrc b/ground/openpilotgcs/src/plugins/config/configgadget.qrc index adffc9568..f58ce7203 100644 --- a/ground/openpilotgcs/src/plugins/config/configgadget.qrc +++ b/ground/openpilotgcs/src/plugins/config/configgadget.qrc @@ -4,6 +4,8 @@ images/ahrs-calib.svg images/paper-plane.svg images/multirotor-shapes.svg + + images/fixedwing-shapes.svg images/ccpm_setup.svg images/PipXtreme.png images/help.png diff --git a/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.cpp b/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.cpp index 8a49d6421..318d71051 100644 --- a/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.cpp @@ -68,9 +68,11 @@ QStringList ConfigVehicleTypeWidget::getChannelDescriptions() QStringList channelDesc; switch (systemSettingsData.AirframeType) { case SystemSettings::AIRFRAMETYPE_FIXEDWING: + channelDesc = ConfigFixedWingWidget::getChannelDescriptions(); + break; case SystemSettings::AIRFRAMETYPE_FIXEDWINGELEVON: + // do nothing for elevon support for the time being. case SystemSettings::AIRFRAMETYPE_FIXEDWINGVTAIL: - // fixed wing channelDesc = ConfigFixedWingWidget::getChannelDescriptions(); break; case SystemSettings::AIRFRAMETYPE_HELICP: diff --git a/ground/openpilotgcs/src/plugins/config/images/fixedwing-shapes.svg b/ground/openpilotgcs/src/plugins/config/images/fixedwing-shapes.svg new file mode 100644 index 000000000..e99a33c65 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/config/images/fixedwing-shapes.svg @@ -0,0 +1,2789 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ground/openpilotgcs/src/plugins/setupwizard/connectiondiagram.cpp b/ground/openpilotgcs/src/plugins/setupwizard/connectiondiagram.cpp index 4a19eb4cf..e69bf039b 100644 --- a/ground/openpilotgcs/src/plugins/setupwizard/connectiondiagram.cpp +++ b/ground/openpilotgcs/src/plugins/setupwizard/connectiondiagram.cpp @@ -118,6 +118,16 @@ void ConnectionDiagram::setupGraphicsScene() } break; case VehicleConfigurationSource::VEHICLE_FIXEDWING: + switch (m_configSource->getVehicleSubType()) { + case VehicleConfigurationSource::FIXED_WING_AILERON: + elementsToShow << "aileron"; + break; + case VehicleConfigurationSource::FIXED_WING_VTAIL: + elementsToShow << "vtail"; + break; + default: + break; + } case VehicleConfigurationSource::VEHICLE_HELI: case VehicleConfigurationSource::VEHICLE_SURFACE: default: diff --git a/ground/openpilotgcs/src/plugins/setupwizard/pages/fixedwingpage.cpp b/ground/openpilotgcs/src/plugins/setupwizard/pages/fixedwingpage.cpp index 7295cc8a3..9dd9b9638 100644 --- a/ground/openpilotgcs/src/plugins/setupwizard/pages/fixedwingpage.cpp +++ b/ground/openpilotgcs/src/plugins/setupwizard/pages/fixedwingpage.cpp @@ -27,16 +27,96 @@ #include "fixedwingpage.h" #include "ui_fixedwingpage.h" +#include "setupwizard.h" FixedWingPage::FixedWingPage(SetupWizard *wizard, QWidget *parent) : AbstractWizardPage(wizard, parent), ui(new Ui::FixedWingPage) { ui->setupUi(this); - setFinalPage(true); + QSvgRenderer *renderer = new QSvgRenderer(); + renderer->load(QString(":/configgadget/images/fixedwing-shapes.svg")); + m_fixedwingPic = new QGraphicsSvgItem(); + m_fixedwingPic->setSharedRenderer(renderer); + QGraphicsScene *scene = new QGraphicsScene(this); + scene->addItem(m_fixedwingPic); + ui->typeGraphicsView->setScene(scene); + + setupFixedWingTypesCombo(); + + // Default to Aileron setup + ui->typeCombo->setCurrentIndex(0); + connect(ui->typeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateImageAndDescription())); + ui->typeGraphicsView->setSceneRect(m_fixedwingPic->boundingRect()); + ui->typeGraphicsView->fitInView(m_fixedwingPic, Qt::KeepAspectRatio); + } FixedWingPage::~FixedWingPage() { delete ui; } + +void FixedWingPage::initializePage() +{ + updateAvailableTypes(); + updateImageAndDescription(); +} + +bool FixedWingPage::validatePage() +{ + SetupWizard::VEHICLE_SUB_TYPE type = (SetupWizard::VEHICLE_SUB_TYPE)ui->typeCombo->itemData(ui->typeCombo->currentIndex()).toInt(); + + getWizard()->setVehicleSubType(type); + return true; +} + +void FixedWingPage::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + if (m_fixedwingPic) { + ui->typeGraphicsView->setSceneRect(m_fixedwingPic->boundingRect()); + ui->typeGraphicsView->fitInView(m_fixedwingPic, Qt::KeepAspectRatio); + } +} + +void FixedWingPage::setupFixedWingTypesCombo() +{ + ui->typeCombo->addItem(tr("Aileron, Elevator, Rudder"), SetupWizard::FIXED_WING_AILERON); + m_descriptions << tr("This setup currently expects a traditional 4 channel setup including two ailerons (not connected by Y adapter), an elevator and a rudder. "); + + ui->typeCombo->addItem(tr("V-Tail"), SetupWizard::FIXED_WING_VTAIL); + m_descriptions << tr("This setup currently expects a flying-wing setup, an elevon plus rudder setup is not yet supported. Setup should include only two elevons, and should explicitly not include a rudder."); +} + +void FixedWingPage::updateAvailableTypes() +{ +} + +void FixedWingPage::updateImageAndDescription() +{ + + + SetupWizard::VEHICLE_SUB_TYPE type = (SetupWizard::VEHICLE_SUB_TYPE)ui->typeCombo->itemData(ui->typeCombo->currentIndex()).toInt(); + QString elementId = ""; + QString description = m_descriptions.at(ui->typeCombo->currentIndex()); + + switch (type) { + case SetupWizard::FIXED_WING_AILERON: + elementId = "aileron"; + break; + case SetupWizard::FIXED_WING_VTAIL: + elementId = "vtail"; + break; + default: + elementId = ""; + break; + } + m_fixedwingPic->setElementId(elementId); + ui->typeGraphicsView->setSceneRect(m_fixedwingPic->boundingRect()); + ui->typeGraphicsView->fitInView(m_fixedwingPic, Qt::KeepAspectRatio); + + ui->typeDescription->setText(description); + +} + diff --git a/ground/openpilotgcs/src/plugins/setupwizard/pages/fixedwingpage.h b/ground/openpilotgcs/src/plugins/setupwizard/pages/fixedwingpage.h index 6a99ef2fe..593be37bb 100644 --- a/ground/openpilotgcs/src/plugins/setupwizard/pages/fixedwingpage.h +++ b/ground/openpilotgcs/src/plugins/setupwizard/pages/fixedwingpage.h @@ -28,6 +28,10 @@ #ifndef FIXEDWINGPAGE_H #define FIXEDWINGPAGE_H +#include +#include +#include + #include "abstractwizardpage.h" namespace Ui { @@ -41,8 +45,21 @@ public: explicit FixedWingPage(SetupWizard *wizard, QWidget *parent = 0); ~FixedWingPage(); + void initializePage(); + bool validatePage(); + +protected: + void resizeEvent(QResizeEvent *event); + private: Ui::FixedWingPage *ui; + void setupFixedWingTypesCombo(); + QGraphicsSvgItem *m_fixedwingPic; + void updateAvailableTypes(); + QList m_descriptions; + +private slots: + void updateImageAndDescription(); }; #endif // FIXEDWINGPAGE_H diff --git a/ground/openpilotgcs/src/plugins/setupwizard/pages/fixedwingpage.ui b/ground/openpilotgcs/src/plugins/setupwizard/pages/fixedwingpage.ui index 8b478be7d..b1c5f253f 100644 --- a/ground/openpilotgcs/src/plugins/setupwizard/pages/fixedwingpage.ui +++ b/ground/openpilotgcs/src/plugins/setupwizard/pages/fixedwingpage.ui @@ -15,22 +15,147 @@ - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">The Fixed Wing section of the OpenPilot Setup Wizard is not yet implemented</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> + p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">OpenPilot fixedwing configuration</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">This part of the wizard will set up the OpenPilot controller for use with a flying platform utilizing multiple rotors. The wizard supports the most common types of fixedwings. Other variants of fixedwings can be configured by using custom configuration options in the Configuration plugin in the GCS.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Please select the type of fixedwing you want to create a configuration for below:</span></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + 4 - - Qt::AlignCenter - - - true - - + + + + + + 4 + + + + + + 125 + 36 + + + + + 10 + 50 + false + + + + FixedWing type: + + + + + + + + 125 + 20 + + + + + + + + + + + 0 + 0 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOff + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + 0 + 0 + + + + + 200 + 200 + + + + true + + + QFrame::NoFrame + + + 0 + + + 0 + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + false + + + + diff --git a/ground/openpilotgcs/src/plugins/setupwizard/pages/outputcalibrationpage.cpp b/ground/openpilotgcs/src/plugins/setupwizard/pages/outputcalibrationpage.cpp index c1eebfa1d..c469fa2cc 100644 --- a/ground/openpilotgcs/src/plugins/setupwizard/pages/outputcalibrationpage.cpp +++ b/ground/openpilotgcs/src/plugins/setupwizard/pages/outputcalibrationpage.cpp @@ -36,13 +36,13 @@ OutputCalibrationPage::OutputCalibrationPage(SetupWizard *wizard, QWidget *paren { ui->setupUi(this); + qDebug() << "calling output calibration page"; m_vehicleRenderer = new QSvgRenderer(); - if (QFile::exists(QString(":/setupwizard/resources/multirotor-shapes.svg")) && - m_vehicleRenderer->load(QString(":/setupwizard/resources/multirotor-shapes.svg")) && - m_vehicleRenderer->isValid()) { - m_vehicleScene = new QGraphicsScene(this); - ui->vehicleView->setScene(m_vehicleScene); - } + + // move the code that was here to setupVehicle() so we can determine which image to use. + m_vehicleScene = new QGraphicsScene(this); + ui->vehicleView->setScene(m_vehicleScene); + } OutputCalibrationPage::~OutputCalibrationPage() @@ -63,8 +63,18 @@ void OutputCalibrationPage::setupVehicle() m_channelIndex.clear(); m_currentWizardIndex = 0; m_vehicleScene->clear(); + +// KF moved code from OutputCalibrationPage() here so it can be used to detect the current vehicle +// needs to be slimmed down and not repeated. + switch (getWizard()->getVehicleSubType()) { case SetupWizard::MULTI_ROTOR_TRI_Y: + if (QFile::exists(QString(":/setupwizard/resources/multirotor-shapes.svg")) && + m_vehicleRenderer->load(QString(":/setupwizard/resources/multirotor-shapes.svg")) && + m_vehicleRenderer->isValid()) { + ui->vehicleView->setScene(m_vehicleScene); + } + m_wizardIndexes << 0 << 1 << 1 << 1 << 2 << 3 << 4; m_vehicleElementIds << "tri" << "tri-frame" << "tri-m1" << "tri-m2" << "tri-m3" << "tri-s1"; m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 4 << 4; @@ -75,35 +85,116 @@ void OutputCalibrationPage::setupVehicle() getWizard()->setActuatorSettings(m_actuatorSettings); break; case SetupWizard::MULTI_ROTOR_QUAD_X: + if (QFile::exists(QString(":/setupwizard/resources/multirotor-shapes.svg")) && + m_vehicleRenderer->load(QString(":/setupwizard/resources/multirotor-shapes.svg")) && + m_vehicleRenderer->isValid()) { + ui->vehicleView->setScene(m_vehicleScene); + } m_wizardIndexes << 0 << 1 << 1 << 1 << 1; m_vehicleElementIds << "quad-x" << "quad-x-frame" << "quad-x-m1" << "quad-x-m2" << "quad-x-m3" << "quad-x-m4"; m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4; m_channelIndex << 0 << 0 << 1 << 2 << 3; break; case SetupWizard::MULTI_ROTOR_QUAD_PLUS: + if (QFile::exists(QString(":/setupwizard/resources/multirotor-shapes.svg")) && + m_vehicleRenderer->load(QString(":/setupwizard/resources/multirotor-shapes.svg")) && + m_vehicleRenderer->isValid()) { + ui->vehicleView->setScene(m_vehicleScene); + } m_wizardIndexes << 0 << 1 << 1 << 1 << 1; m_vehicleElementIds << "quad-p" << "quad-p-frame" << "quad-p-m1" << "quad-p-m2" << "quad-p-m3" << "quad-p-m4"; m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4; m_channelIndex << 0 << 0 << 1 << 2 << 3; break; case SetupWizard::MULTI_ROTOR_HEXA: + if (QFile::exists(QString(":/setupwizard/resources/multirotor-shapes.svg")) && + m_vehicleRenderer->load(QString(":/setupwizard/resources/multirotor-shapes.svg")) && + m_vehicleRenderer->isValid()) { + ui->vehicleView->setScene(m_vehicleScene); + } m_wizardIndexes << 0 << 1 << 1 << 1 << 1 << 1 << 1; m_vehicleElementIds << "hexa" << "hexa-frame" << "hexa-m1" << "hexa-m2" << "hexa-m3" << "hexa-m4" << "hexa-m5" << "hexa-m6"; m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 5 << 6; m_channelIndex << 0 << 0 << 1 << 2 << 3 << 4 << 5; break; case SetupWizard::MULTI_ROTOR_HEXA_COAX_Y: + if (QFile::exists(QString(":/setupwizard/resources/multirotor-shapes.svg")) && + m_vehicleRenderer->load(QString(":/setupwizard/resources/multirotor-shapes.svg")) && + m_vehicleRenderer->isValid()) { + ui->vehicleView->setScene(m_vehicleScene); + } m_wizardIndexes << 0 << 1 << 1 << 1 << 1 << 1 << 1; m_vehicleElementIds << "hexa-y6" << "hexa-y6-frame" << "hexa-y6-m2" << "hexa-y6-m1" << "hexa-y6-m4" << "hexa-y6-m3" << "hexa-y6-m6" << "hexa-y6-m5"; m_vehicleHighlightElementIndexes << 0 << 2 << 1 << 4 << 3 << 6 << 5; m_channelIndex << 0 << 0 << 1 << 2 << 3 << 4 << 5; break; case SetupWizard::MULTI_ROTOR_HEXA_H: + if (QFile::exists(QString(":/setupwizard/resources/multirotor-shapes.svg")) && + m_vehicleRenderer->load(QString(":/setupwizard/resources/multirotor-shapes.svg")) && + m_vehicleRenderer->isValid()) { + ui->vehicleView->setScene(m_vehicleScene); + } m_wizardIndexes << 0 << 1 << 1 << 1 << 1 << 1 << 1; m_vehicleElementIds << "hexa-h" << "hexa-h-frame" << "hexa-h-m1" << "hexa-h-m2" << "hexa-h-m3" << "hexa-h-m4" << "hexa-h-m5" << "hexa-h-m6"; m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 5 << 6; m_channelIndex << 0 << 0 << 1 << 2 << 3 << 4 << 5; break; +// KF hack + case SetupWizard::FIXED_WING_AILERON: + if (QFile::exists(QString(":/setupwizard/resources/fixedwing-shapes.svg")) && + m_vehicleRenderer->load(QString(":/setupwizard/resources/fixedwing-shapes.svg")) && + m_vehicleRenderer->isValid()) { + ui->vehicleView->setScene(m_vehicleScene); + } + qDebug() << "no clue what a wizard index is!"; + m_wizardIndexes << 0 << 1 << 3 << 3 << 3 << 3; // These come from OutputCalibrationPage::setWizardPage() + m_vehicleElementIds << "fixed-aileron" << "aileron"; + m_vehicleHighlightElementIndexes << 0 << 1; + m_channelIndex << 0 << 0 << 1 << 2 << 3 << 4; + + // see Servo city for an example. 1500 usec is center on MS85mg for example. - http://www.servocity.com/html/hs-85mg__mighty_micro.html + // make sure Aileron servo one does not go to an extreme value + m_actuatorSettings[1].channelMin = 1500; + m_actuatorSettings[1].channelNeutral = 1500; + m_actuatorSettings[1].channelMax = 1500; + // make sure Aileron servo two does not go to an extreme value + m_actuatorSettings[2].channelMin = 1500; + m_actuatorSettings[2].channelNeutral = 1500; + m_actuatorSettings[2].channelMax = 1500; + // make sure Elevator servo one does not go to an extreme value + m_actuatorSettings[3].channelMin = 1500; + m_actuatorSettings[4].channelNeutral = 1500; + m_actuatorSettings[3].channelMax = 1500; + // make sure Rudder servo one does not go to an extreme value + m_actuatorSettings[4].channelMin = 1500; + m_actuatorSettings[4].channelNeutral = 1500; + m_actuatorSettings[4].channelMax = 1500; + + getWizard()->setActuatorSettings(m_actuatorSettings); + break; + case SetupWizard::FIXED_WING_VTAIL: + if (QFile::exists(QString(":/setupwizard/resources/fixedwing-shapes.svg")) && + m_vehicleRenderer->load(QString(":/setupwizard/resources/fixedwing-shapes.svg")) && + m_vehicleRenderer->isValid()) { + ui->vehicleView->setScene(m_vehicleScene); + } + qDebug() << "no clue what a wizard index is!"; + m_wizardIndexes << 0 << 1 << 3 << 3; // These come from OutputCalibrationPage::setWizardPage() + m_vehicleElementIds << "fixed-vtail" << "vtail"; + m_vehicleHighlightElementIndexes << 0 << 1; + m_channelIndex << 0 << 0 << 1 << 2; + + // make sure elevon servo one does not go to an extreme value + m_actuatorSettings[1].channelMin = 1500; + m_actuatorSettings[1].channelNeutral = 1500; + m_actuatorSettings[1].channelMax = 1500; + // make sure elevon servo two does not go to an extreme value + m_actuatorSettings[2].channelMin = 1500; + m_actuatorSettings[2].channelNeutral = 1500; + m_actuatorSettings[2].channelMax = 1500; + + getWizard()->setActuatorSettings(m_actuatorSettings); + break; default: break; } @@ -191,7 +282,7 @@ void OutputCalibrationPage::setWizardPage() ui->servoMaxAngleSlider->setValue(m_actuatorSettings[currentChannel].channelMax); } } - setupVehicleHighlightedPart(); + // setupVehicleHighlightedPart(); // turn this off for now, need to fix fixedwing image elements } void OutputCalibrationPage::initializePage() diff --git a/ground/openpilotgcs/src/plugins/setupwizard/pages/vehiclepage.ui b/ground/openpilotgcs/src/plugins/setupwizard/pages/vehiclepage.ui index a6e0e9354..34d9531fe 100644 --- a/ground/openpilotgcs/src/plugins/setupwizard/pages/vehiclepage.ui +++ b/ground/openpilotgcs/src/plugins/setupwizard/pages/vehiclepage.ui @@ -146,7 +146,7 @@ p, li { white-space: pre-wrap; } - false + true diff --git a/ground/openpilotgcs/src/plugins/setupwizard/resources/fixedwing-shapes.svg b/ground/openpilotgcs/src/plugins/setupwizard/resources/fixedwing-shapes.svg new file mode 100644 index 000000000..e99a33c65 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/setupwizard/resources/fixedwing-shapes.svg @@ -0,0 +1,2789 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ground/openpilotgcs/src/plugins/setupwizard/setupwizard.cpp b/ground/openpilotgcs/src/plugins/setupwizard/setupwizard.cpp index de3b20063..449296f5b 100644 --- a/ground/openpilotgcs/src/plugins/setupwizard/setupwizard.cpp +++ b/ground/openpilotgcs/src/plugins/setupwizard/setupwizard.cpp @@ -112,6 +112,9 @@ int SetupWizard::nextId() const case PAGE_MULTI: return PAGE_OUTPUT; + case PAGE_FIXEDWING: + return PAGE_OUTPUT; + case PAGE_INPUT: if (isRestartNeeded()) { saveHardwareSettings(); @@ -225,7 +228,22 @@ QString SetupWizard::getSummaryText() break; case VEHICLE_FIXEDWING: - summary.append(tr("Fixed wing")); + summary.append(tr("Fixed wing")); + + summary.append("
"); + summary.append("").append(tr("Vehicle sub type: ")).append(""); + switch (getVehicleSubType()) { + case SetupWizard::FIXED_WING_AILERON: + summary.append(tr("Aileron")); + break; + case SetupWizard::FIXED_WING_VTAIL: + summary.append(tr("Vtail")); + break; + default: + summary.append(tr("Unknown")); + break; + } + break; case VEHICLE_HELI: summary.append(tr("Helicopter")); diff --git a/ground/openpilotgcs/src/plugins/setupwizard/vehicleconfigurationhelper.cpp b/ground/openpilotgcs/src/plugins/setupwizard/vehicleconfigurationhelper.cpp index 6d8e0fd7d..5de6ae900 100644 --- a/ground/openpilotgcs/src/plugins/setupwizard/vehicleconfigurationhelper.cpp +++ b/ground/openpilotgcs/src/plugins/setupwizard/vehicleconfigurationhelper.cpp @@ -214,6 +214,19 @@ void VehicleConfigurationHelper::applyVehicleConfiguration() break; } case VehicleConfigurationSource::VEHICLE_FIXEDWING: + { + switch (m_configSource->getVehicleSubType()) { + case VehicleConfigurationSource::FIXED_WING_AILERON: + setupAileron(); + break; + case VehicleConfigurationSource::FIXED_WING_VTAIL: + setupVtail(); + break; + default: + break; + } + break; + } case VehicleConfigurationSource::VEHICLE_HELI: case VehicleConfigurationSource::VEHICLE_SURFACE: // TODO: Implement settings for other vehicle types? @@ -293,7 +306,23 @@ void VehicleConfigurationHelper::applyActuatorConfiguration() addModifiedObject(actSettings, tr("Writing actuator settings")); break; } +/* case VehicleConfigurationSource::VEHICLE_FIXEDWING: + { + ActuatorSettings::DataFields data = actSettings->getData(); + + qDebug() << "Override center pulse for fixed wing servos\n"; + // move all but first chan to 1500 center pluse + QList actuatorSettings = m_configSource->getActuatorSettings(); + for (quint16 i = 1; i < ActuatorSettings::CHANNELMAX_NUMELEM; i++) { + data.ChannelType[i] = ActuatorSettings::CHANNELTYPE_PWM; + data.ChannelAddr[i] = i; + data.ChannelMin[i] = 1500; + data.ChannelNeutral[i] = 1500; + data.ChannelMax[i] = 1500; + } + } +*/ case VehicleConfigurationSource::VEHICLE_HELI: case VehicleConfigurationSource::VEHICLE_SURFACE: // TODO: Implement settings for other vehicle types? @@ -1287,3 +1316,93 @@ void VehicleConfigurationHelper::setupOctoCopter() applyMixerConfiguration(channels); applyMultiGUISettings(frame, guiSettings); } + +void VehicleConfigurationHelper::setupVtail() +{ + + mixerChannelSettings channels[10]; + GUIConfigDataUnion guiSettings = getGUIConfigData(); + + channels[0].type = MIXER_TYPE_MOTOR; + channels[0].throttle1 = 100; + channels[0].throttle2 = 0; + channels[0].roll = 0; + channels[0].pitch = 0; + channels[0].yaw = 0; + + channels[1].type = MIXER_TYPE_SERVO; + channels[1].throttle1 = 0; + channels[1].throttle2 = 0; + channels[1].roll = -100; + channels[1].pitch = 50; + channels[1].yaw = 0; + + channels[2].type = MIXER_TYPE_SERVO; + channels[2].throttle1 = 0; + channels[2].throttle2 = 0; + channels[2].roll = 100; + channels[2].pitch = -50; + channels[2].yaw = 0; + + guiSettings.fixedwing.FixedWingThrottle = 1; + guiSettings.fixedwing.FixedWingRoll1 = 2; + guiSettings.fixedwing.FixedWingRoll2 = 3; + + applyMixerConfiguration(channels); + applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_FIXEDWINGVTAIL, guiSettings); +} + +void VehicleConfigurationHelper::setupAileron() +{ + // Typical vehicle setup + // 1. Setup mixer data + // 2. Setup GUI data + // 3. Apply changes + + mixerChannelSettings channels[10]; + GUIConfigDataUnion guiSettings = getGUIConfigData(); + + channels[0].type = MIXER_TYPE_MOTOR; + channels[0].throttle1 = 100; + channels[0].throttle2 = 0; + channels[0].roll = 0; + channels[0].pitch = 0; + channels[0].yaw = 0; + + channels[1].type = MIXER_TYPE_SERVO; + channels[1].throttle1 = 0; + channels[1].throttle2 = 0; + channels[1].roll = -100; + channels[1].pitch = 0; + channels[1].yaw = 0; + + channels[2].type = MIXER_TYPE_SERVO; + channels[2].throttle1 = 0; + channels[2].throttle2 = 0; + channels[2].roll = 100; + channels[2].pitch = 0; + channels[2].yaw = 0; + + channels[3].type = MIXER_TYPE_SERVO; + channels[3].throttle1 = 0; + channels[3].throttle2 = 0; + channels[3].roll = 0; + channels[3].pitch = 100; + channels[3].yaw = 0; + + channels[3].type = MIXER_TYPE_SERVO; + channels[3].throttle1 = 0; + channels[3].throttle2 = 0; + channels[3].roll = 0; + channels[3].pitch = 0; + channels[3].yaw = 100; + + guiSettings.fixedwing.FixedWingThrottle = 1; + guiSettings.fixedwing.FixedWingRoll1 = 2; + guiSettings.fixedwing.FixedWingRoll2 = 3; + guiSettings.fixedwing.FixedWingPitch1 = 4; + guiSettings.fixedwing.FixedWingYaw1 = 5; + + applyMixerConfiguration(channels); + applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_FIXEDWING, guiSettings); +} diff --git a/ground/openpilotgcs/src/plugins/setupwizard/vehicleconfigurationhelper.h b/ground/openpilotgcs/src/plugins/setupwizard/vehicleconfigurationhelper.h index 1ed1aa576..d3ef88df4 100644 --- a/ground/openpilotgcs/src/plugins/setupwizard/vehicleconfigurationhelper.h +++ b/ground/openpilotgcs/src/plugins/setupwizard/vehicleconfigurationhelper.h @@ -103,6 +103,8 @@ private: void setupQuadCopter(); void setupHexaCopter(); void setupOctoCopter(); + void setupVtail(); + void setupAileron(); private slots: void uAVOTransactionCompleted(UAVObject *object, bool success); diff --git a/ground/openpilotgcs/src/plugins/setupwizard/wizardResources.qrc b/ground/openpilotgcs/src/plugins/setupwizard/wizardResources.qrc index 1ee031d0e..507b4c877 100644 --- a/ground/openpilotgcs/src/plugins/setupwizard/wizardResources.qrc +++ b/ground/openpilotgcs/src/plugins/setupwizard/wizardResources.qrc @@ -30,6 +30,8 @@ resources/bttn-turbo-down.png resources/bttn-turbo-up.png resources/multirotor-shapes.svg + + resources/fixedwing-shapes.svg resources/bttn-illustration-down.png resources/bttn-illustration-up.png resources/bttn-save-down.png