diff --git a/ground/gcs/src/plugins/config/configgadgetwidget.cpp b/ground/gcs/src/plugins/config/configgadgetwidget.cpp index 512aecce4..8f3776205 100644 --- a/ground/gcs/src/plugins/config/configgadgetwidget.cpp +++ b/ground/gcs/src/plugins/config/configgadgetwidget.cpp @@ -77,6 +77,8 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent) ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); QWidget *widget; + QWidget *inputWidget; + QWidget *outputWidget; QIcon *icon; icon = new QIcon(); @@ -98,6 +100,7 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent) widget = new ConfigInputWidget(this); static_cast(widget)->bind(); stackWidget->insertTab(ConfigGadgetWidget::Input, widget, *icon, QString("Input")); + inputWidget = widget; icon = new QIcon(); icon->addFile(":/configgadget/images/output_normal.png", QSize(), QIcon::Normal, QIcon::Off); @@ -105,6 +108,7 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent) widget = new ConfigOutputWidget(this); static_cast(widget)->bind(); stackWidget->insertTab(ConfigGadgetWidget::Output, widget, *icon, QString("Output")); + outputWidget = widget; icon = new QIcon(); icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off); @@ -165,6 +169,11 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent) onOPLinkConnect(); } + // Connect output tab and input tab for safe + // output config and input calibration + connect(outputWidget, SIGNAL(outputConfigSafe(bool)), inputWidget, SLOT(outputConfigSafe(bool))); + connect(inputWidget, SIGNAL(inputCalibrationStatus(bool)), outputWidget, SLOT(inputCalibrationStatus(bool))); + help = 0; connect(stackWidget, SIGNAL(currentAboutToShow(int, bool *)), this, SLOT(tabAboutToChange(int, bool *))); } diff --git a/ground/gcs/src/plugins/config/configinputwidget.cpp b/ground/gcs/src/plugins/config/configinputwidget.cpp index 6ce93d59f..49c94dd9d 100644 --- a/ground/gcs/src/plugins/config/configinputwidget.cpp +++ b/ground/gcs/src/plugins/config/configinputwidget.cpp @@ -509,6 +509,12 @@ void ConfigInputWidget::resizeEvent(QResizeEvent *event) void ConfigInputWidget::goToWizard() { + if (!safeOutputConfig) { + QMessageBox::warning(this, tr("Warning"), tr("There is something wrong in Output tab." + "

Please fix the issue before starting the Transmitter wizard

"), QMessageBox::Ok); + return; + } + QMessageBox msgBox; msgBox.setText(tr("Arming Settings are now set to 'Always Disarmed' for your safety.")); @@ -519,6 +525,9 @@ void ConfigInputWidget::goToWizard() msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); + // Tell Output tab we freeze actuators soon + emit inputCalibrationStatus(true); + // Set correct tab visible before starting wizard. if (ui->tabWidget->currentIndex() != 0) { ui->tabWidget->setCurrentIndex(0); @@ -587,6 +596,9 @@ void ConfigInputWidget::wzCancel() flightModeSettingsObj->setData(memento.flightModeSettingsData); actuatorSettingsObj->setData(memento.actuatorSettingsData); systemSettingsObj->setData(memento.systemSettingsData); + + // Tell Output tab the calibration is ended + emit inputCalibrationStatus(false); } void ConfigInputWidget::registerControlActivity() @@ -682,6 +694,9 @@ void ConfigInputWidget::wzNext() // move to Arming Settings tab ui->stackedWidget->setCurrentIndex(0); ui->tabWidget->setCurrentIndex(3); + + // Tell Output tab the calibration is ended + emit inputCalibrationStatus(false); break; default: Q_ASSERT(0); @@ -1916,6 +1931,15 @@ void ConfigInputWidget::updateCalibration() void ConfigInputWidget::simpleCalibration(bool enable) { + if (!safeOutputConfig) { + if (enable) { + QMessageBox::warning(this, tr("Warning"), tr("There is something wrong in Output tab." + "

Please fix the issue before starting the Manual Calibration

"), QMessageBox::Ok); + ui->runCalibration->setChecked(false); + } + return; + } + if (enable) { ui->configurationWizard->setEnabled(false); ui->applyButton->setEnabled(false); @@ -1932,6 +1956,9 @@ void ConfigInputWidget::simpleCalibration(bool enable) msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); + // Tell Output tab we freeze actuators soon + emit inputCalibrationStatus(true); + manualCommandData = manualCommandObj->getData(); manualSettingsData = manualSettingsObj->getData(); @@ -1999,6 +2026,9 @@ void ConfigInputWidget::simpleCalibration(bool enable) ui->saveButton->setEnabled(true); ui->runCalibration->setText(tr("Start Manual Calibration")); + // Tell Output tab the calibration is ended + emit inputCalibrationStatus(false); + disconnect(manualCommandObj, SIGNAL(objectUnpacked(UAVObject *)), this, SLOT(updateCalibration())); } } @@ -2082,7 +2112,7 @@ void ConfigInputWidget::resetActuatorSettings() QString mixerType; // Clear all output data : Min, max, neutral at same value - // 1000 for motors and 1500 for all others (Reversable motor included) + // min value for motors and neutral for all others (Reversable motor, servo) for (unsigned int output = 0; output < ActuatorSettings::CHANNELMAX_NUMELEM; output++) { QString mixerNumType = QString("Mixer%1Type").arg(output + 1); UAVObjectField *field = mixer->getField(mixerNumType); @@ -2092,13 +2122,13 @@ void ConfigInputWidget::resetActuatorSettings() mixerType = field->getValue().toString(); } if ((mixerType == "Motor") || (mixerType == "Disabled")) { - actuatorSettingsData.ChannelMax[output] = 1000; - actuatorSettingsData.ChannelMin[output] = 1000; - actuatorSettingsData.ChannelNeutral[output] = 1000; + // Apply current min setting to neutral/max values + actuatorSettingsData.ChannelMax[output] = actuatorSettingsData.ChannelMin[output]; + actuatorSettingsData.ChannelNeutral[output] = actuatorSettingsData.ChannelMin[output]; } else { - actuatorSettingsData.ChannelMax[output] = 1500; - actuatorSettingsData.ChannelMin[output] = 1500; - actuatorSettingsData.ChannelNeutral[output] = 1500; + // Apply current neutral setting to min/max values + actuatorSettingsData.ChannelMax[output] = actuatorSettingsData.ChannelNeutral[output]; + actuatorSettingsData.ChannelMin[output] = actuatorSettingsData.ChannelNeutral[output]; } UAVObjectUpdaterHelper updateHelper; actuatorSettingsObj->setData(actuatorSettingsData, false); @@ -2189,3 +2219,8 @@ void ConfigInputWidget::enableControlsChanged(bool enabled) ui->failsafeBatteryWarningFlightModeCb->setEnabled(enabled && batteryModuleEnabled); ui->failsafeBatteryCriticalFlightModeCb->setEnabled(enabled && batteryModuleEnabled); } + +void ConfigInputWidget::outputConfigSafe(bool status) +{ + safeOutputConfig = status; +} diff --git a/ground/gcs/src/plugins/config/configinputwidget.h b/ground/gcs/src/plugins/config/configinputwidget.h index 996e83d94..f2289a211 100644 --- a/ground/gcs/src/plugins/config/configinputwidget.h +++ b/ground/gcs/src/plugins/config/configinputwidget.h @@ -72,10 +72,17 @@ public: void enableControls(bool enable); bool shouldObjectBeSaved(UAVObject *object); +public slots: + void outputConfigSafe(bool status); + +signals: + void inputCalibrationStatus(bool started); + private: bool throttleError; bool growing; bool reverse[ManualControlSettings::CHANNELNEUTRAL_NUMELEM]; + bool safeOutputConfig; txMovements currentMovement; int movePos; void setTxMovement(txMovements movement); diff --git a/ground/gcs/src/plugins/config/configoutputwidget.cpp b/ground/gcs/src/plugins/config/configoutputwidget.cpp index 374dc9d61..95137a549 100644 --- a/ground/gcs/src/plugins/config/configoutputwidget.cpp +++ b/ground/gcs/src/plugins/config/configoutputwidget.cpp @@ -667,7 +667,7 @@ void ConfigOutputWidget::onBankTypeChange() updateChannelConfigWarning(warning_found); } -bool ConfigOutputWidget::checkOutputConfig() +void ConfigOutputWidget::checkOutputConfig() { ChannelConfigWarning current_warning = None; ChannelConfigWarning warning_found = None; @@ -691,11 +691,8 @@ bool ConfigOutputWidget::checkOutputConfig() updateChannelConfigWarning(warning_found); - if (warning_found > None) { - return false; - } - - return true; + // Emit signal to be received by Input tab + emit outputConfigSafe(warning_found == None); } void ConfigOutputWidget::stopTests() @@ -779,6 +776,12 @@ QString ConfigOutputWidget::bankModeName(int index) return bankModeOptions.at(index); } +void ConfigOutputWidget::inputCalibrationStatus(bool started) +{ + // Disable controls if a input calibration is started + enableControls(!started); +} + OutputBankControls::OutputBankControls(MixerSettings *mixer, QLabel *label, QColor color, QComboBox *rateCombo, QComboBox *modeCombo) : m_mixer(mixer), m_label(label), m_color(color), m_rateCombo(rateCombo), m_modeCombo(modeCombo) {} diff --git a/ground/gcs/src/plugins/config/configoutputwidget.h b/ground/gcs/src/plugins/config/configoutputwidget.h index a58be8fd6..6313fff9c 100644 --- a/ground/gcs/src/plugins/config/configoutputwidget.h +++ b/ground/gcs/src/plugins/config/configoutputwidget.h @@ -85,7 +85,11 @@ public: ConfigOutputWidget(QWidget *parent = 0); ~ConfigOutputWidget(); - bool checkOutputConfig(); +public slots: + void inputCalibrationStatus(bool started); + +signals: + void outputConfigSafe(bool status); protected: void enableControls(bool enable); @@ -102,6 +106,8 @@ private: UAVObject::Metadata m_accInitialData; QList m_banks; + bool inputCalibrationStarted; + OutputChannelForm *getOutputChannelForm(const int index) const; void updateChannelInSlider(QSlider *slider, QLabel *min, QLabel *max, QCheckBox *rev, int value); void assignOutputChannel(UAVDataObject *obj, QString &str); @@ -110,6 +116,7 @@ private: enum ChannelConfigWarning { None, CannotDriveServo, IsNormalMotorCheckNeutral, IsReversibleMotorCheckNeutral, BiDirectionalDShotNotSupported }; void setChannelLimits(OutputChannelForm *channelForm, OutputBankControls *bankControls); ChannelConfigWarning checkChannelConfig(OutputChannelForm *channelForm, OutputBankControls *bankControls); + void checkOutputConfig(); void updateChannelConfigWarning(ChannelConfigWarning warning); QString bankModeName(int index);