void ConfigStabilizationWidget::resetThrottleCurveToDefault() { UAVDataObject *defaultStabBank = (UAVDataObject *)getObjectManager()->getObject(QString(m_stabTabBars.at(0)->tabData(m_currentStabSettingsBank).toString())); Q_ASSERT(defaultStabBank); defaultStabBank = defaultStabBank->dirtyClone(); UAVObjectField *field = defaultStabBank->getField("ThrustPIDScaleCurve"); Q_ASSERT(field); QList<double> curve; for (quint32 i = 0; i < field->getNumElements(); i++) { curve.append(field->getValue(i).toDouble()); } ui->thrustPIDScalingCurve->setCurve(&curve); field = defaultStabBank->getField("EnableThrustPIDScaling"); Q_ASSERT(field); bool enabled = field->getValue() == "TRUE"; ui->enableThrustPIDScalingCheckBox->setChecked(enabled); ui->thrustPIDScalingCurve->setEnabled(enabled); delete defaultStabBank; }
/** * Set the dropdown option for a channel output assignement */ void ConfigServoWidget::assignOutputChannel(UAVDataObject *obj, QString str) { UAVObjectField* field = obj->getField(str); QStringList options = field->getOptions(); switch (options.indexOf(field->getValue().toString())) { case 0: m_config->ch0Output->setCurrentIndex(m_config->ch0Output->findText(str)); break; case 1: m_config->ch1Output->setCurrentIndex(m_config->ch1Output->findText(str)); break; case 2: m_config->ch2Output->setCurrentIndex(m_config->ch2Output->findText(str)); break; case 3: m_config->ch3Output->setCurrentIndex(m_config->ch3Output->findText(str)); break; case 4: m_config->ch4Output->setCurrentIndex(m_config->ch4Output->findText(str)); break; case 5: m_config->ch5Output->setCurrentIndex(m_config->ch5Output->findText(str)); break; case 6: m_config->ch6Output->setCurrentIndex(m_config->ch6Output->findText(str)); break; case 7: m_config->ch7Output->setCurrentIndex(m_config->ch7Output->findText(str)); break; } }
void EscCalibrationPage::startButtonClicked() { if (!m_isCalibrating) { m_isCalibrating = true; ui->startButton->setEnabled(false); enableButtons(false); ui->outputHigh->setEnabled(true); ui->outputLow->setEnabled(false); ui->nonconnectedLabel->setEnabled(false); ui->connectedLabel->setEnabled(true); ui->outputLevel->setText(QString(tr("%1 µs")).arg(HIGH_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS)); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectManager *uavoManager = pm->getObject<UAVObjectManager>(); Q_ASSERT(uavoManager); MixerSettings *mSettings = MixerSettings::GetInstance(uavoManager); Q_ASSERT(mSettings); QString mixerTypePattern = "Mixer%1Type"; OutputCalibrationUtil::startOutputCalibration(); for (quint32 i = 0; i < ActuatorSettings::CHANNELADDR_NUMELEM; i++) { UAVObjectField *field = mSettings->getField(mixerTypePattern.arg(i + 1)); Q_ASSERT(field); if (field->getValue().toString() == field->getOptions().at(VehicleConfigurationHelper::MIXER_TYPE_MOTOR)) { m_outputChannels << i; } } m_outputUtil.startChannelOutput(m_outputChannels, OFF_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS); QThread::msleep(100); m_outputUtil.setChannelOutputValue(HIGH_PWM_OUTPUT_PULSE_LENGTH_MICROSECONDS); ui->stopButton->setEnabled(true); } }
/** Refreshes the current value of the SystemSettings which holds the aircraft type Note: The default behavior of ConfigTaskWidget is bypassed. Therefore no automatic synchronization of UAV Objects to UI is done. */ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *o) { Q_UNUSED(o); if (!allObjectsUpdated()) { return; } bool dirty = isDirty(); // Get the Airframe type from the system settings: UAVDataObject *system = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("SystemSettings"))); Q_ASSERT(system); UAVObjectField *field = system->getField(QString("AirframeType")); Q_ASSERT(field); // At this stage, we will need to have some hardcoded settings in this code QString frameType = field->getValue().toString(); // Always update custom tab from others airframe settings : debug/learn hardcoded mixers int category = frameCategory("Custom"); m_aircraft->aircraftType->setCurrentIndex(category); VehicleConfig *vehicleConfig = getVehicleConfigWidget(category); if (vehicleConfig) { vehicleConfig->refreshWidgetsValues("Custom"); } // Switch to Airframe currently used category = frameCategory(frameType); if (frameType != "Custom") { m_aircraft->aircraftType->setCurrentIndex(category); VehicleConfig *vehicleConfig = getVehicleConfigWidget(category); if (vehicleConfig) { vehicleConfig->refreshWidgetsValues(frameType); } } field = system->getField(QString("VehicleName")); Q_ASSERT(field); QString name; for (uint i = 0; i < field->getNumElements(); ++i) { QChar chr = field->getValue(i).toChar(); if (chr != 0) { name.append(chr); } else { break; } } m_aircraft->nameEdit->setText(name); updateFeedForwardUI(); setDirty(dirty); }
void ConfigStabilizationWidget::updateThrottleCurveFromObject() { bool dirty = isDirty(); UAVObject *stabBank = getObjectManager()->getObject(QString(m_stabTabBars.at(0)->tabData(m_currentStabSettingsBank).toString())); Q_ASSERT(stabBank); UAVObjectField *field = stabBank->getField("ThrustPIDScaleCurve"); Q_ASSERT(field); QList<double> curve; for (quint32 i = 0; i < field->getNumElements(); i++) { curve.append(field->getValue(i).toDouble()); } ui->thrustPIDScalingCurve->setCurve(&curve); field = stabBank->getField("EnableThrustPIDScaling"); Q_ASSERT(field); bool enabled = field->getValue() == "TRUE"; ui->enableThrustPIDScalingCheckBox->setChecked(enabled); ui->thrustPIDScalingCurve->setEnabled(enabled); setDirty(dirty); }
/*! \brief Called when the flight mode drop down is changed and sets the ManualControlCommand->FlightMode accordingly */ void GCSControlGadgetWidget::selectFlightMode(int state) { ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVDataObject* obj = dynamic_cast<UAVDataObject*>( objManager->getObject(QString("FlightStatus")) ); UAVObjectField * field = obj->getField("FlightMode"); field->setValue(field->getOptions()[state]); obj->updated(); }
/** Saves the AHRS sensors calibration (to RAM and SD) */ void ConfigAHRSWidget::saveAHRSCalibration() { UAVObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSCalibration"))); UAVObjectField *field = obj->getField(QString("measure_var")); field->setValue("SET"); obj->updated(); updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj); }
QString UsageTrackerPlugin::getUAVFieldValue(UAVObjectManager *objManager, QString objectName, QString fieldName, int index) const { UAVObject *object = objManager->getObject(objectName); if (object != NULL) { UAVObjectField *field = object->getField(fieldName); if (field != NULL) { return field->getValue(index).toString(); } } return tr("Unknown"); }
/** * Slot called by visualization when a new @ref PositionDesired is requested */ void MagicWaypointGadgetWidget::positionSelected(double north, double east) { double scale = m_magicwaypoint->horizontalSliderScale->value(); PositionDesired * posDesired = getPositionDesired(); if(posDesired) { UAVObjectField * field = posDesired->getField("North"); if(field) field->setDouble(north * scale); field = posDesired->getField("East"); if(field) field->setDouble(east * scale); posDesired->updated(); } }
/** Launches the AHRS sensors calibration */ void ConfigAHRSWidget::launchAHRSCalibration() { m_ahrs->calibInstructions->setText("Estimating sensor variance..."); m_ahrs->ahrsCalibStart->setEnabled(false); UAVObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSCalibration"))); UAVObjectField *field = obj->getField(QString("measure_var")); field->setValue("MEASURE"); obj->updated(); QTimer::singleShot(calibrationDelay*1000, this, SLOT(calibPhase2())); m_ahrs->calibProgress->setRange(0,calibrationDelay); phaseCounter = 0; progressBarIndex = 0; connect(&progressBarTimer, SIGNAL(timeout()), this, SLOT(incrementProgress())); progressBarTimer.start(1000); }
void VehicleConfigurationHelper::applyMixerConfiguration(mixerChannelSettings channels[]) { // Set all mixer data MixerSettings *mSettings = MixerSettings::GetInstance(m_uavoManager); Q_ASSERT(mSettings); // Set Mixer types and values QString mixerTypePattern = "Mixer%1Type"; QString mixerVectorPattern = "Mixer%1Vector"; for (int i = 0; i < 10; i++) { UAVObjectField *field = mSettings->getField(mixerTypePattern.arg(i + 1)); Q_ASSERT(field); field->setValue(field->getOptions().at(channels[i].type)); field = mSettings->getField(mixerVectorPattern.arg(i + 1)); Q_ASSERT(field); field->setValue((channels[i].throttle1 * 127) / 100, 0); field->setValue((channels[i].throttle2 * 127) / 100, 1); field->setValue((channels[i].roll * 127) / 100, 2); field->setValue((channels[i].pitch * 127) / 100, 3); field->setValue((channels[i].yaw * 127) / 100, 4); } // Apply updates mSettings->setData(mSettings->getData()); addModifiedObject(mSettings, tr("Writing mixer settings")); }
void ConfigStabilizationWidget::updateObjectFromThrottleCurve() { UAVObject *stabBank = getObjectManager()->getObject(QString(m_stabTabBars.at(0)->tabData(m_currentStabSettingsBank).toString())); Q_ASSERT(stabBank); UAVObjectField *field = stabBank->getField("ThrustPIDScaleCurve"); Q_ASSERT(field); QList<double> curve = ui->thrustPIDScalingCurve->getCurve(); for (quint32 i = 0; i < field->getNumElements(); i++) { field->setValue(curve.at(i), i); } field = stabBank->getField("EnableThrustPIDScaling"); Q_ASSERT(field); field->setValue(ui->enableThrustPIDScalingCheckBox->isChecked() ? "TRUE" : "FALSE"); }
/** Sends the channel value to the UAV to move the servo. Returns immediately if we are not in testing mode */ void ConfigOutputWidget::sendChannelTest(int value) { int in_value = value; QSlider *ob = (QSlider *)QObject::sender(); if (!ob) return; int index = outSliders.indexOf(ob); if (index < 0) return; if (reversals[index]->isChecked()) value = outMin[index]->value() - value + outMax[index]->value(); // the chsnnel is reversed // update the label outLabels[index]->setText(QString::number(value)); if (links[index]->checkState()) { // the channel is linked to other channels // set the linked channels to the same value for (int i = 0; i < outSliders.count(); i++) { if (i == index) continue; if (!links[i]->checkState()) continue; int val = in_value; if (val < outSliders[i]->minimum()) val = outSliders[i]->minimum(); if (val > outSliders[i]->maximum()) val = outSliders[i]->maximum(); if (outSliders[i]->value() == val) continue; outSliders[i]->setValue(val); outLabels[i]->setText(QString::number(val)); } } if (!m_config->channelOutTest->isChecked()) return; UAVDataObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorCommand"))); if (!obj) return; UAVObjectField *channel = obj->getField("Channel"); if (!channel) return; channel->setValue(value, index); obj->updated(); }
/** Request the current config from the board */ void ConfigInputWidget::refreshValues() { UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ManualControlSettings"))); Q_ASSERT(obj); //obj->requestUpdate(); UAVObjectField *field; // Now update all the slider values: UAVObjectField *field_max = obj->getField(QString("ChannelMax")); UAVObjectField *field_min = obj->getField(QString("ChannelMin")); UAVObjectField *field_neu = obj->getField(QString("ChannelNeutral")); Q_ASSERT(field_max); Q_ASSERT(field_min); Q_ASSERT(field_neu); for (int i = 0; i < 8; i++) { QVariant max = field_max->getValue(i); QVariant min = field_min->getValue(i); QVariant neutral = field_neu->getValue(i); inMaxLabels[i]->setText(max.toString()); inMinLabels[i]->setText(min.toString()); if (max.toInt()> min.toInt()) { inRevCheckboxes[i]->setChecked(false); inSliders[i]->setMaximum(max.toInt()); inSliders[i]->setMinimum(min.toInt()); } else { inRevCheckboxes[i]->setChecked(true); inSliders[i]->setMaximum(min.toInt()); inSliders[i]->setMinimum(max.toInt()); } inSliders[i]->setValue(neutral.toInt()); } // Update receiver type field = obj->getField(QString("InputMode")); m_config->receiverType->setText(field->getValue().toString()); // Reset all channel assignement dropdowns: foreach (QComboBox *combo, inChannelAssign) { combo->setCurrentIndex(0); }
/** Sends the channel value to the UAV to move the servo. Returns immediately if we are not in testing mode */ void ConfigServoWidget::sendChannelTest(int value) { // First of all, update the label: QSlider *ob = (QSlider*)QObject::sender(); int index = outSliders.indexOf(ob); if (reversals[index]->isChecked()) value = outMin[index]->value()-value+outMax[index]->value(); else outLabels[index]->setText(QString::number(value)); outLabels[index]->setText(QString::number(value)); if (!m_config->channelOutTest->isChecked()) return; UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorCommand"))); UAVObjectField * channel = obj->getField("Channel"); channel->setValue(value,index); obj->updated(); }
ConfigCustomWidget::ConfigCustomWidget(QWidget *parent) : VehicleConfig(parent), m_aircraft(new Ui_CustomConfigWidget()) { m_aircraft->setupUi(this); // Put combo boxes in line one of the custom mixer table: UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); UAVObjectField *field = mixer->getField(QString("Mixer1Type")); QStringList list = field->getOptions(); for (int i = 0; i < (int)VehicleConfig::CHANNEL_NUMELEM; 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 < (int)VehicleConfig::CHANNEL_NUMELEM; i++) { m_aircraft->customMixerTable->setItemDelegateForRow(i, sbd); } }
/** Refreshes the current value of the SystemSettings which holds the aircraft type Note: The default behavior of ConfigTaskWidget is bypassed. Therefore no automatic synchronization of UAV Objects to UI is done. */ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *o) { Q_UNUSED(o); if (!allObjectsUpdated()) { return; } bool dirty = isDirty(); // Get the Airframe type from the system settings: UAVDataObject *system = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("SystemSettings"))); Q_ASSERT(system); UAVObjectField *field = system->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 there you go. QString frameType = field->getValue().toString(); qDebug() << "ConfigVehicleTypeWidget::refreshWidgetsValues - frame type:" << frameType; QString category = frameCategory(frameType); setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText(category)); VehicleConfig *vehicleConfig = getVehicleConfigWidget(category); if (vehicleConfig) { vehicleConfig->refreshWidgetsValues(frameType); } updateFeedForwardUI(); setDirty(dirty); qDebug() << "ConfigVehicleTypeWidget::refreshWidgetsValues - end"; }
ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_config = new Ui_InputWidget(); m_config->setupUi(this); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); // First of all, put all the channel widgets into lists, so that we can // manipulate those: inMaxLabels << m_config->ch0Max << m_config->ch1Max << m_config->ch2Max << m_config->ch3Max << m_config->ch4Max << m_config->ch5Max << m_config->ch6Max << m_config->ch7Max; inMinLabels << m_config->ch0Min << m_config->ch1Min << m_config->ch2Min << m_config->ch3Min << m_config->ch4Min << m_config->ch5Min << m_config->ch6Min << m_config->ch7Min; inSliders << m_config->inSlider0 << m_config->inSlider1 << m_config->inSlider2 << m_config->inSlider3 << m_config->inSlider4 << m_config->inSlider5 << m_config->inSlider6 << m_config->inSlider7; inRevCheckboxes << m_config->ch0Rev << m_config->ch1Rev << m_config->ch2Rev << m_config->ch3Rev << m_config->ch4Rev << m_config->ch5Rev << m_config->ch6Rev << m_config->ch7Rev; inChannelAssign << m_config->ch0Assign << m_config->ch1Assign << m_config->ch2Assign << m_config->ch3Assign << m_config->ch4Assign << m_config->ch5Assign << m_config->ch6Assign << m_config->ch7Assign; // Now connect the widget to the ManualControlCommand / Channel UAVObject UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlCommand"))); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateChannels(UAVObject*))); // Register for ManualControlSettings changes: obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings"))); connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues())); // Get the receiver types supported by OpenPilot and fill the corresponding // dropdown menu: obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings"))); UAVObjectField * field; // Fill in the dropdown menus for the channel RC Input assignement. QStringList channelsList; channelsList << "None"; QList<UAVObjectField*> fieldList = obj->getFields(); foreach (UAVObjectField* field, fieldList) { if (field->getUnits().contains("channel")) { channelsList.append(field->getName()); } } m_config->ch0Assign->addItems(channelsList); m_config->ch1Assign->addItems(channelsList); m_config->ch2Assign->addItems(channelsList); m_config->ch3Assign->addItems(channelsList); m_config->ch4Assign->addItems(channelsList); m_config->ch5Assign->addItems(channelsList); m_config->ch6Assign->addItems(channelsList); m_config->ch7Assign->addItems(channelsList); // And the flight mode settings: field = obj->getField(QString("FlightModePosition")); m_config->fmsModePos1->addItems(field->getOptions()); m_config->fmsModePos2->addItems(field->getOptions()); m_config->fmsModePos3->addItems(field->getOptions()); field = obj->getField(QString("Stabilization1Settings")); channelsList.clear(); channelsList.append(field->getOptions()); m_config->fmsSsPos1Roll->addItems(channelsList); m_config->fmsSsPos1Pitch->addItems(channelsList); m_config->fmsSsPos1Yaw->addItems(channelsList); m_config->fmsSsPos2Roll->addItems(channelsList); m_config->fmsSsPos2Pitch->addItems(channelsList); m_config->fmsSsPos2Yaw->addItems(channelsList); m_config->fmsSsPos3Roll->addItems(channelsList); m_config->fmsSsPos3Pitch->addItems(channelsList); m_config->fmsSsPos3Yaw->addItems(channelsList); // And the Armin configurations: field = obj->getField(QString("Arming")); m_config->armControl->clear(); m_config->armControl->addItems(field->getOptions()); connect(m_config->saveRCInputToSD, SIGNAL(clicked()), this, SLOT(saveRCInputObject())); connect(m_config->saveRCInputToRAM, SIGNAL(clicked()), this, SLOT(sendRCInputUpdate())); enableControls(false); refreshValues(); connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect())); connect(parent, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect())); connect(m_config->ch0Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool))); connect(m_config->ch1Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool))); connect(m_config->ch2Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool))); connect(m_config->ch3Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool))); connect(m_config->ch4Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool))); connect(m_config->ch5Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool))); connect(m_config->ch6Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool))); connect(m_config->ch7Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool))); connect(m_config->doRCInputCalibration,SIGNAL(stateChanged(int)),this,SLOT(updateTips(int))); firstUpdate = true; // Connect the help button connect(m_config->inputHelp, SIGNAL(clicked()), this, SLOT(openHelp())); updateTips(Qt::Unchecked); }
ConfigServoWidget::ConfigServoWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_config = new Ui_SettingsWidget(); m_config->setupUi(this); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); // First of all, put all the channel widgets into lists, so that we can // manipulate those: // NOTE: for historical reasons, we have objects below called ch0 to ch7, but the convention for OP is Channel 1 to Channel 8. outLabels << m_config->ch0OutValue << m_config->ch1OutValue << m_config->ch2OutValue << m_config->ch3OutValue << m_config->ch4OutValue << m_config->ch5OutValue << m_config->ch6OutValue << m_config->ch7OutValue; outSliders << m_config->ch0OutSlider << m_config->ch1OutSlider << m_config->ch2OutSlider << m_config->ch3OutSlider << m_config->ch4OutSlider << m_config->ch5OutSlider << m_config->ch6OutSlider << m_config->ch7OutSlider; outMin << m_config->ch0OutMin << m_config->ch1OutMin << m_config->ch2OutMin << m_config->ch3OutMin << m_config->ch4OutMin << m_config->ch5OutMin << m_config->ch6OutMin << m_config->ch7OutMin; outMax << m_config->ch0OutMax << m_config->ch1OutMax << m_config->ch2OutMax << m_config->ch3OutMax << m_config->ch4OutMax << m_config->ch5OutMax << m_config->ch6OutMax << m_config->ch7OutMax; reversals << m_config->ch0Rev << m_config->ch1Rev << m_config->ch2Rev << m_config->ch3Rev << m_config->ch4Rev << m_config->ch5Rev << m_config->ch6Rev << m_config->ch7Rev; inMaxLabels << m_config->ch0Max << m_config->ch1Max << m_config->ch2Max << m_config->ch3Max << m_config->ch4Max << m_config->ch5Max << m_config->ch6Max << m_config->ch7Max; inMinLabels << m_config->ch0Min << m_config->ch1Min << m_config->ch2Min << m_config->ch3Min << m_config->ch4Min << m_config->ch5Min << m_config->ch6Min << m_config->ch7Min; inNeuLabels << m_config->ch0Cur << m_config->ch1Cur << m_config->ch2Cur << m_config->ch3Cur << m_config->ch4Cur << m_config->ch5Cur << m_config->ch6Cur << m_config->ch7Cur; inSliders << m_config->inSlider0 << m_config->inSlider1 << m_config->inSlider2 << m_config->inSlider3 << m_config->inSlider4 << m_config->inSlider5 << m_config->inSlider6 << m_config->inSlider7; // Now connect the widget to the ManualControlCommand / Channel UAVObject UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlCommand"))); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateChannels(UAVObject*))); // Get the receiver types supported by OpenPilot and fill the corresponding // dropdown menu: obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings"))); QString fieldName = QString("InputMode"); UAVObjectField *field = obj->getField(fieldName); m_config->receiverType->addItems(field->getOptions()); m_config->receiverType->setDisabled(true); // This option does not work for now, it is a compile-time option. // Fill in the dropdown menus for the channel RC Input assignement. QStringList channelsList; channelsList << "None"; QList<UAVObjectField*> fieldList = obj->getFields(); foreach (UAVObjectField* field, fieldList) { if (field->getUnits().contains("channel")) { channelsList.append(field->getName()); } } m_config->ch0Assign->addItems(channelsList); m_config->ch1Assign->addItems(channelsList); m_config->ch2Assign->addItems(channelsList); m_config->ch3Assign->addItems(channelsList); m_config->ch4Assign->addItems(channelsList); m_config->ch5Assign->addItems(channelsList); m_config->ch6Assign->addItems(channelsList); m_config->ch7Assign->addItems(channelsList); // And for the channel output assignement options m_config->ch0Output->addItem("None"); m_config->ch1Output->addItem("None"); m_config->ch2Output->addItem("None"); m_config->ch3Output->addItem("None"); m_config->ch4Output->addItem("None"); m_config->ch5Output->addItem("None"); m_config->ch6Output->addItem("None"); m_config->ch7Output->addItem("None"); // And the flight mode settings: field = obj->getField(QString("FlightModePosition")); m_config->fmsModePos1->addItems(field->getOptions()); m_config->fmsModePos2->addItems(field->getOptions()); m_config->fmsModePos3->addItems(field->getOptions()); field = obj->getField(QString("Stabilization1Settings")); channelsList.clear(); channelsList.append(field->getOptions()); m_config->fmsSsPos1Roll->addItems(channelsList); m_config->fmsSsPos1Pitch->addItems(channelsList); m_config->fmsSsPos1Yaw->addItems(channelsList); m_config->fmsSsPos2Roll->addItems(channelsList); m_config->fmsSsPos2Pitch->addItems(channelsList); m_config->fmsSsPos2Yaw->addItems(channelsList); m_config->fmsSsPos3Roll->addItems(channelsList); m_config->fmsSsPos3Pitch->addItems(channelsList); m_config->fmsSsPos3Yaw->addItems(channelsList); // And the Armin configurations: field = obj->getField(QString("Arming")); m_config->armControl->clear(); m_config->armControl->addItems(field->getOptions()); obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings"))); fieldList = obj->getFields(); foreach (UAVObjectField* field, fieldList) { if (field->getUnits().contains("channel")) { m_config->ch0Output->addItem(field->getName()); m_config->ch1Output->addItem(field->getName()); m_config->ch2Output->addItem(field->getName()); m_config->ch3Output->addItem(field->getName()); m_config->ch4Output->addItem(field->getName()); m_config->ch5Output->addItem(field->getName()); m_config->ch6Output->addItem(field->getName()); m_config->ch7Output->addItem(field->getName()); } } // set the RC input tneutral value textees for (int i = 0; i < 8; i++) inNeuLabels[i]->setText(QString::number(inSliders[i]->value())); for (int i = 0; i < 8; i++) { connect(outMin[i], SIGNAL(editingFinished()), this, SLOT(setChOutRange())); connect(outMax[i], SIGNAL(editingFinished()), this, SLOT(setChOutRange())); connect(reversals[i], SIGNAL(toggled(bool)), this, SLOT(reverseChannel(bool))); // Now connect the channel out sliders to our signal to send updates in test mode connect(outSliders[i], SIGNAL(valueChanged(int)), this, SLOT(sendChannelTest(int))); } connect(m_config->channelOutTest, SIGNAL(toggled(bool)), this, SLOT(runChannelTests(bool))); requestRCInputUpdate(); requestRCOutputUpdate(); connect(m_config->saveRCInputToSD, SIGNAL(clicked()), this, SLOT(saveRCInputObject())); connect(m_config->saveRCInputToRAM, SIGNAL(clicked()), this, SLOT(sendRCInputUpdate())); connect(m_config->getRCInputCurrent, SIGNAL(clicked()), this, SLOT(requestRCInputUpdate())); // Flightmode panel is connected to the same as rcinput because // the underlying object is the same! connect(m_config->saveFmsToSD, SIGNAL(clicked()), this, SLOT(saveRCInputObject())); connect(m_config->saveFmsToRAM, SIGNAL(clicked()), this, SLOT(sendRCInputUpdate())); connect(m_config->getFmsCurrent, SIGNAL(clicked()), this, SLOT(requestRCInputUpdate())); connect(m_config->saveArmToSD, SIGNAL(clicked()), this, SLOT(saveRCInputObject())); connect(m_config->saveArmToRAM, SIGNAL(clicked()), this, SLOT(sendRCInputUpdate())); connect(m_config->getArmCurrent, SIGNAL(clicked()), this, SLOT(requestRCInputUpdate())); connect(m_config->saveRCOutputToSD, SIGNAL(clicked()), this, SLOT(saveRCOutputObject())); connect(m_config->saveRCOutputToRAM, SIGNAL(clicked()), this, SLOT(sendRCOutputUpdate())); connect(m_config->getRCOutputCurrent, SIGNAL(clicked()), this, SLOT(requestRCOutputUpdate())); connect(parent, SIGNAL(autopilotConnected()),this, SLOT(requestRCInputUpdate())); connect(parent, SIGNAL(autopilotConnected()),this, SLOT(requestRCOutputUpdate())); connect(m_config->inSlider0, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged0(int))); connect(m_config->inSlider1, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged1(int))); connect(m_config->inSlider2, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged2(int))); connect(m_config->inSlider3, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged3(int))); connect(m_config->inSlider4, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged4(int))); connect(m_config->inSlider5, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged5(int))); connect(m_config->inSlider6, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged6(int))); connect(m_config->inSlider7, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged7(int))); firstUpdate = true; enableControls(false); // Listen to telemetry connection events if (pm) { TelemetryManager *tm = pm->getObject<TelemetryManager>(); if (tm) { connect(tm, SIGNAL(myStart()), this, SLOT(onTelemetryStart())); connect(tm, SIGNAL(myStop()), this, SLOT(onTelemetryStop())); connect(tm, SIGNAL(connected()), this, SLOT(onTelemetryConnect())); connect(tm, SIGNAL(disconnected()), this, SLOT(onTelemetryDisconnect())); } } }
/** Request the current config from the board (RC Output) */ void ConfigServoWidget::requestRCOutputUpdate() { ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); // Get the Airframe type from the system settings: UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("SystemSettings"))); Q_ASSERT(obj); obj->requestUpdate(); UAVObjectField *field = obj->getField(QString("AirframeType")); m_config->aircraftType->setText(QString("Aircraft type: ") + field->getValue().toString()); // Reset all channel assignements: m_config->ch0Output->setCurrentIndex(0); m_config->ch1Output->setCurrentIndex(0); m_config->ch2Output->setCurrentIndex(0); m_config->ch3Output->setCurrentIndex(0); m_config->ch4Output->setCurrentIndex(0); m_config->ch5Output->setCurrentIndex(0); m_config->ch6Output->setCurrentIndex(0); m_config->ch7Output->setCurrentIndex(0); // Get the channel assignements: obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings"))); Q_ASSERT(obj); obj->requestUpdate(); QList<UAVObjectField*> fieldList = obj->getFields(); foreach (UAVObjectField* field, fieldList) { if (field->getUnits().contains("channel")) { assignOutputChannel(obj,field->getName()); } } // Get Output rates for both banks field = obj->getField(QString("ChannelUpdateFreq")); m_config->outputRate1->setValue(field->getValue(0).toInt()); m_config->outputRate2->setValue(field->getValue(1).toInt()); // Get Channel ranges: for (int i=0;i<8;i++) { field = obj->getField(QString("ChannelMin")); int minValue = field->getValue(i).toInt(); outMin[i]->setValue(minValue); field = obj->getField(QString("ChannelMax")); int maxValue = field->getValue(i).toInt(); outMax[i]->setValue(maxValue); if (maxValue>minValue) { outSliders[i]->setMinimum(minValue); outSliders[i]->setMaximum(maxValue); reversals[i]->setChecked(false); } else { outSliders[i]->setMinimum(maxValue); outSliders[i]->setMaximum(minValue); reversals[i]->setChecked(true); } } field = obj->getField(QString("ChannelNeutral")); for (int i=0; i<8; i++) { int value = field->getValue(i).toInt(); outSliders[i]->setValue(value); outLabels[i]->setText(QString::number(value)); } }
ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_config = new Ui_OutputWidget(); m_config->setupUi(this); ExtensionSystem::PluginManager *pm=ExtensionSystem::PluginManager::instance(); Core::Internal::GeneralSettings * settings=pm->getObject<Core::Internal::GeneralSettings>(); if(!settings->useExpertMode()) m_config->saveRCOutputToRAM->setVisible(false); /* There's lots of situations where it's unsafe to run tests. * Import/export: */ UAVSettingsImportExportFactory * importexportplugin = pm->getObject<UAVSettingsImportExportFactory>(); connect(importexportplugin,SIGNAL(importAboutToBegin()),this,SLOT(stopTests())); /* Board connection/disconnection: */ TelemetryManager* telMngr = pm->getObject<TelemetryManager>(); connect(telMngr, SIGNAL(connected()), this, SLOT(stopTests())); connect(telMngr, SIGNAL(disconnected()), this, SLOT(stopTests())); /* When we go into wizards, etc.. time to stop this too. */ Core::ModeManager *modeMngr = Core::ModeManager::instance(); connect(modeMngr, SIGNAL(currentModeAboutToChange(Core::IMode *)), this, SLOT(stopTests())); connect(modeMngr, SIGNAL(currentModeChanged(Core::IMode *)), this, SLOT(stopTests())); // NOTE: we have channel indices from 0 to 9, but the convention for OP is Channel 1 to Channel 10. // Register for ActuatorSettings changes: for (unsigned int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) { OutputChannelForm *outputForm = new OutputChannelForm(i, this, i==0); m_config->channelLayout->addWidget(outputForm); connect(m_config->channelOutTest, SIGNAL(toggled(bool)), outputForm, SLOT(enableChannelTest(bool))); connect(outputForm, SIGNAL(channelChanged(int,int)), this, SLOT(sendChannelTest(int,int))); connect(outputForm, SIGNAL(formChanged()), this, SLOT(do_SetDirty())); } connect(m_config->channelOutTest, SIGNAL(toggled(bool)), this, SLOT(runChannelTests(bool))); connect(m_config->calibrateESC, SIGNAL(clicked()), this, SLOT(startESCCalibration())); // Configure the task widget // Connect the help button connect(m_config->outputHelp, SIGNAL(clicked()), this, SLOT(openHelp())); addApplySaveButtons(m_config->saveRCOutputToRAM,m_config->saveRCOutputToSD); // Track the ActuatorSettings object addUAVObject("ActuatorSettings"); // Associate the buttons with their UAVO fields addWidget(m_config->cb_outputRate6); addWidget(m_config->cb_outputRate5); addWidget(m_config->cb_outputRate4); addWidget(m_config->cb_outputRate3); addWidget(m_config->cb_outputRate2); addWidget(m_config->cb_outputRate1); addWidget(m_config->spinningArmed); // Cache all the combo boxes and labels lblList.clear(); lblList << m_config->chBank1 << m_config->chBank2 << m_config->chBank3 << m_config->chBank4 << m_config->chBank5 << m_config->chBank6; rateList.clear(); rateList << m_config->cb_outputRate1 << m_config->cb_outputRate2 << m_config->cb_outputRate3 << m_config->cb_outputRate4 << m_config->cb_outputRate5 << m_config->cb_outputRate6; resList.clear(); resList << m_config->cb_outputResolution1 << m_config->cb_outputResolution2 << m_config->cb_outputResolution3 << m_config->cb_outputResolution4 << m_config->cb_outputResolution5 << m_config->cb_outputResolution6; // Get the list of output resolutions and assign to the resolution dropdowns ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager()); Q_ASSERT(actuatorSettings); UAVObjectField *resolutions = actuatorSettings->getField("TimerPwmResolution"); Q_ASSERT(resolutions); QList<QComboBox*>::iterator resIter; for (resIter = resList.begin(); resIter != resList.end(); resIter++) { QComboBox *res = *resIter; res->clear(); res->addItems(resolutions->getOptions()); addWidget(res); connect(res, SIGNAL(currentIndexChanged(int)), this, SLOT(refreshWidgetRanges())); } QList<QComboBox*>::iterator rateIter; for (rateIter = rateList.begin(); rateIter != rateList.end(); rateIter++) { QComboBox *rate = *rateIter; connect(rate, SIGNAL(currentIndexChanged(int)), this, SLOT(refreshWidgetRanges())); } disconnect(this, SLOT(refreshWidgetsValues(UAVObject*))); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObject* obj = objManager->getObject(QString("ActuatorCommand")); if(UAVObject::GetGcsTelemetryUpdateMode(obj->getMetadata()) == UAVObject::UPDATEMODE_ONCHANGE) this->setEnabled(false); connect(SystemSettings::GetInstance(objManager), SIGNAL(objectUpdated(UAVObject*)),this,SLOT(assignOutputChannels(UAVObject*))); refreshWidgetsValues(); }
/** * Sends the config to the board, without saving to the SD card (RC Output) */ void ConfigServoWidget::sendRCOutputUpdate() { ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings"))); Q_ASSERT(obj); // Now send channel ranges: UAVObjectField * field = obj->getField(QString("ChannelMax")); for (int i = 0; i < 8; i++) { field->setValue(outMax[i]->value(),i); } field = obj->getField(QString("ChannelMin")); for (int i = 0; i < 8; i++) { field->setValue(outMin[i]->value(),i); } field = obj->getField(QString("ChannelNeutral")); for (int i = 0; i < 8; i++) { field->setValue(outSliders[i]->value(),i); } field = obj->getField(QString("ChannelUpdateFreq")); field->setValue(m_config->outputRate1->value(),0); field->setValue(m_config->outputRate2->value(),1); // Set Actuator assignement for each channel: // Rule: if two channels have the same setting (which is wrong!) the higher channel // will get the setting. // First, reset all channel assignements: QList<UAVObjectField*> fieldList = obj->getFields(); 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()); } } if (m_config->ch0Output->currentIndex() != 0) { field = obj->getField(m_config->ch0Output->currentText()); field->setValue(field->getOptions().at(0)); // -> This way we don't depend on channel naming convention } if (m_config->ch1Output->currentIndex() != 0) { field = obj->getField(m_config->ch1Output->currentText()); field->setValue(field->getOptions().at(1)); // -> This way we don't depend on channel naming convention } if (m_config->ch2Output->currentIndex() != 0) { field = obj->getField(m_config->ch2Output->currentText()); field->setValue(field->getOptions().at(2)); // -> This way we don't depend on channel naming convention } if (m_config->ch3Output->currentIndex() != 0) { field = obj->getField(m_config->ch3Output->currentText()); field->setValue(field->getOptions().at(3)); // -> This way we don't depend on channel naming convention } if (m_config->ch4Output->currentIndex() != 0) { field = obj->getField(m_config->ch4Output->currentText()); field->setValue(field->getOptions().at(4)); // -> This way we don't depend on channel naming convention } if (m_config->ch5Output->currentIndex() != 0) { field = obj->getField(m_config->ch5Output->currentText()); field->setValue(field->getOptions().at(5)); // -> This way we don't depend on channel naming convention } if (m_config->ch6Output->currentIndex() != 0) { field = obj->getField(m_config->ch6Output->currentText()); field->setValue(field->getOptions().at(6)); // -> This way we don't depend on channel naming convention } if (m_config->ch7Output->currentIndex() != 0) { field = obj->getField(m_config->ch7Output->currentText()); field->setValue(field->getOptions().at(7)); // -> This way we don't depend on channel naming convention } // ... and send to the OP Board obj->updated(); }
/*! \brief Called by updates to @OPLinkStatus */ void ConfigPipXtremeWidget::updateStatus(UAVObject *object) { // Request and update of the setting object if we haven't received it yet. if (!settingsUpdated) { oplinkSettingsObj->requestUpdate(); } // Update the link state UAVObjectField *linkField = object->getField("LinkState"); m_oplink->LinkState->setText(linkField->getValue().toString()); bool linkConnected = (linkField->getValue() == linkField->getOptions().at(OPLinkStatus::LINKSTATE_CONNECTED)); bool modemEnabled = linkConnected || (linkField->getValue() == linkField->getOptions().at(OPLinkStatus::LINKSTATE_DISCONNECTED)) || (linkField->getValue() == linkField->getOptions().at(OPLinkStatus::LINKSTATE_ENABLED)); UAVObjectField *pairRssiField = object->getField("PairSignalStrengths"); bool bound; bool ok; quint32 boundPairId = m_oplink->CoordID->text().toUInt(&ok, 16); // Update the detected devices. UAVObjectField *pairIdField = object->getField("PairIDs"); quint32 pairid = pairIdField->getValue(0).toUInt(); bound = (pairid == boundPairId); m_oplink->PairID1->setText(QString::number(pairid, 16).toUpper()); m_oplink->PairID1->setEnabled(false); m_oplink->Bind1->setText(bound ? tr("Unbind") : tr("Bind")); m_oplink->Bind1->setEnabled(pairid && modemEnabled); m_oplink->PairSignalStrengthBar1->setValue(((bound && !linkConnected) || !modemEnabled) ? -127 : pairRssiField->getValue(0).toInt()); m_oplink->PairSignalStrengthLabel1->setText(QString("%1dB").arg(m_oplink->PairSignalStrengthBar1->value())); pairid = pairIdField->getValue(1).toUInt(); bound = (pairid == boundPairId); m_oplink->PairID2->setText(QString::number(pairid, 16).toUpper()); m_oplink->PairID2->setEnabled(false); m_oplink->Bind2->setText(bound ? tr("Unbind") : tr("Bind")); m_oplink->Bind2->setEnabled(pairid && modemEnabled); m_oplink->PairSignalStrengthBar2->setValue(((bound && !linkConnected) || !modemEnabled) ? -127 : pairRssiField->getValue(1).toInt()); m_oplink->PairSignalStrengthLabel2->setText(QString("%1dB").arg(m_oplink->PairSignalStrengthBar2->value())); pairid = pairIdField->getValue(2).toUInt(); bound = (pairid == boundPairId); m_oplink->PairID3->setText(QString::number(pairid, 16).toUpper()); m_oplink->PairID3->setEnabled(false); m_oplink->Bind3->setText(bound ? tr("Unbind") : tr("Bind")); m_oplink->Bind3->setEnabled(pairid && modemEnabled); m_oplink->PairSignalStrengthBar3->setValue(((bound && !linkConnected) || !modemEnabled) ? -127 : pairRssiField->getValue(2).toInt()); m_oplink->PairSignalStrengthLabel3->setText(QString("%1dB").arg(m_oplink->PairSignalStrengthBar3->value())); pairid = pairIdField->getValue(3).toUInt(); bound = (pairid == boundPairId); m_oplink->PairID4->setText(QString::number(pairid, 16).toUpper()); m_oplink->PairID4->setEnabled(false); m_oplink->Bind4->setText(bound ? tr("Unbind") : tr("Bind")); m_oplink->Bind4->setEnabled(pairid && modemEnabled); m_oplink->PairSignalStrengthBar4->setValue(((bound && !linkConnected) || !modemEnabled) ? -127 : pairRssiField->getValue(3).toInt()); m_oplink->PairSignalStrengthLabel4->setText(QString("%1dB").arg(m_oplink->PairSignalStrengthBar4->value())); // Update the Description field // TODO use UAVObjectUtilManager::descriptionToStructure() UAVObjectField *descField = object->getField("Description"); if (descField->getValue(0) != QChar(255)) { /* * This looks like a binary with a description at the end: * 4 bytes: header: "OpFw". * 4 bytes: GIT commit tag (short version of SHA1). * 4 bytes: Unix timestamp of compile time. * 2 bytes: target platform. Should follow same rule as BOARD_TYPE and BOARD_REVISION in board define files. * 26 bytes: commit tag if it is there, otherwise branch name. '-dirty' may be added if needed. Zero-padded. * 20 bytes: SHA1 sum of the firmware. * 20 bytes: SHA1 sum of the uavo definitions. * 20 bytes: free for now. */ char buf[OPLinkStatus::DESCRIPTION_NUMELEM]; for (unsigned int i = 0; i < 26; ++i) { buf[i] = descField->getValue(i + 14).toChar().toLatin1(); } buf[26] = '\0'; QString descstr(buf); quint32 gitDate = descField->getValue(11).toChar().toLatin1() & 0xFF; for (int i = 1; i < 4; i++) { gitDate = gitDate << 8; gitDate += descField->getValue(11 - i).toChar().toLatin1() & 0xFF; } QString date = QDateTime::fromTime_t(gitDate).toUTC().toString("yyyy-MM-dd HH:mm"); m_oplink->FirmwareVersion->setText(descstr + " " + date); } else { m_oplink->FirmwareVersion->setText(tr("Unknown")); } // Update the serial number field UAVObjectField *serialField = object->getField("CPUSerial"); char buf[OPLinkStatus::CPUSERIAL_NUMELEM * 2 + 1]; for (unsigned int i = 0; i < OPLinkStatus::CPUSERIAL_NUMELEM; ++i) { unsigned char val = serialField->getValue(i).toUInt() >> 4; buf[i * 2] = ((val < 10) ? '0' : '7') + val; val = serialField->getValue(i).toUInt() & 0xf; buf[i * 2 + 1] = ((val < 10) ? '0' : '7') + val; } buf[OPLinkStatus::CPUSERIAL_NUMELEM * 2] = '\0'; m_oplink->SerialNumber->setText(buf); updateEnableControls(); }
// Slot called by the menu manager on user action void UAVSettingsImportExportFactory::importUAVSettings() { // ask for file name QString fileName; QString filters = tr("UAVObjects XML files (*.uav);; XML files (*.xml)"); fileName = QFileDialog::getOpenFileName(0, tr("Import UAV Settings"), "", filters); if (fileName.isEmpty()) { return; } // Now open the file QFile file(fileName); QDomDocument doc("UAVObjects"); file.open(QFile::ReadOnly | QFile::Text); if (!doc.setContent(file.readAll())) { QMessageBox msgBox; msgBox.setText(tr("File Parsing Failed.")); msgBox.setInformativeText(tr("This file is not a correct XML file")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.exec(); return; } file.close(); // find the root of settings subtree emit importAboutToBegin(); qDebug() << "Import about to begin"; QDomElement root = doc.documentElement(); if (root.tagName() == "uavobjects") { root = root.firstChildElement("settings"); } if (root.isNull() || (root.tagName() != "settings")) { QMessageBox msgBox; msgBox.setText(tr("Wrong file contents")); msgBox.setInformativeText(tr("This file does not contain correct UAVSettings")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.exec(); return; } // We are now ok: setup the import summary dialog & update it as we // go along. ImportSummaryDialog swui((QWidget *)Core::ICore::instance()->mainWindow()); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); swui.show(); QDomNode node = root.firstChild(); while (!node.isNull()) { QDomElement e = node.toElement(); if (e.tagName() == "object") { // - Read each object QString uavObjectName = e.attribute("name"); uint uavObjectID = e.attribute("id").toUInt(NULL, 16); // Sanity Check: UAVObject *obj = objManager->getObject(uavObjectName); if (obj == NULL) { // This object is unknown! qDebug() << "Object unknown:" << uavObjectName << uavObjectID; swui.addLine(uavObjectName, "Error (Object unknown)", false); } else { // - Update each field // - Issue and "updated" command bool error = false; bool setError = false; QDomNode field = node.firstChild(); while (!field.isNull()) { QDomElement f = field.toElement(); if (f.tagName() == "field") { UAVObjectField *uavfield = obj->getField(f.attribute("name")); if (uavfield) { QStringList list = f.attribute("values").split(","); if (list.length() == 1) { if (false == uavfield->checkValue(f.attribute("values"))) { qDebug() << "checkValue returned false on: " << uavObjectName << f.attribute("values"); setError = true; } else { uavfield->setValue(f.attribute("values")); } } else { // This is an enum: int i = 0; QStringList list = f.attribute("values").split(","); foreach(QString element, list) { if (false == uavfield->checkValue(element, i)) { qDebug() << "checkValue(list) returned false on: " << uavObjectName << list; setError = true; } else { uavfield->setValue(element, i); } i++; } } } else { error = true; } } field = field.nextSibling(); } obj->updated(); if (error) { swui.addLine(uavObjectName, "Warning (Object field unknown)", true); } else if (uavObjectID != obj->getObjID()) { qDebug() << "Mismatch for Object " << uavObjectName << uavObjectID << " - " << obj->getObjID(); swui.addLine(uavObjectName, "Warning (ObjectID mismatch)", true); } else if (setError) { swui.addLine(uavObjectName, "Warning (Objects field value(s) invalid)", false); } else { swui.addLine(uavObjectName, "OK", true); } }
ConfigAHRSWidget::ConfigAHRSWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_ahrs = new Ui_AHRSWidget(); m_ahrs->setupUi(this); // Initialization of the Paper plane widget m_ahrs->sixPointsHelp->setScene(new QGraphicsScene(this)); paperplane = new QGraphicsSvgItem(); paperplane->setSharedRenderer(new QSvgRenderer()); paperplane->renderer()->load(QString(":/configgadget/images/paper-plane.svg")); paperplane->setElementId("plane-horizontal"); m_ahrs->sixPointsHelp->scene()->addItem(paperplane); m_ahrs->sixPointsHelp->setSceneRect(paperplane->boundingRect()); // Initialization of the AHRS bargraph graph m_ahrs->ahrsBargraph->setScene(new QGraphicsScene(this)); QSvgRenderer *renderer = new QSvgRenderer(); ahrsbargraph = new QGraphicsSvgItem(); renderer->load(QString(":/configgadget/images/ahrs-calib.svg")); ahrsbargraph->setSharedRenderer(renderer); ahrsbargraph->setElementId("background"); ahrsbargraph->setObjectName("background"); m_ahrs->ahrsBargraph->scene()->addItem(ahrsbargraph); m_ahrs->ahrsBargraph->setSceneRect(ahrsbargraph->boundingRect()); // Initialize the 9 bargraph values: QMatrix lineMatrix = renderer->matrixForElement("accel_x"); QRectF rect = lineMatrix.mapRect(renderer->boundsOnElement("accel_x")); qreal startX = rect.x(); qreal startY = rect.y()+ rect.height(); // maxBarHeight will be used for scaling it later. maxBarHeight = rect.height(); // Then once we have the initial location, we can put it // into a QGraphicsSvgItem which we will display at the same // place: we do this so that the heading scale can be clipped to // the compass dial region. accel_x = new QGraphicsSvgItem(); accel_x->setSharedRenderer(renderer); accel_x->setElementId("accel_x"); m_ahrs->ahrsBargraph->scene()->addItem(accel_x); accel_x->setPos(startX, startY); accel_x->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("accel_y"); rect = lineMatrix.mapRect(renderer->boundsOnElement("accel_y")); startX = rect.x(); startY = rect.y()+ rect.height(); accel_y = new QGraphicsSvgItem(); accel_y->setSharedRenderer(renderer); accel_y->setElementId("accel_y"); m_ahrs->ahrsBargraph->scene()->addItem(accel_y); accel_y->setPos(startX,startY); accel_y->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("accel_z"); rect = lineMatrix.mapRect(renderer->boundsOnElement("accel_z")); startX = rect.x(); startY = rect.y()+ rect.height(); accel_z = new QGraphicsSvgItem(); accel_z->setSharedRenderer(renderer); accel_z->setElementId("accel_z"); m_ahrs->ahrsBargraph->scene()->addItem(accel_z); accel_z->setPos(startX,startY); accel_z->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("gyro_x"); rect = lineMatrix.mapRect(renderer->boundsOnElement("gyro_x")); startX = rect.x(); startY = rect.y()+ rect.height(); gyro_x = new QGraphicsSvgItem(); gyro_x->setSharedRenderer(renderer); gyro_x->setElementId("gyro_x"); m_ahrs->ahrsBargraph->scene()->addItem(gyro_x); gyro_x->setPos(startX,startY); gyro_x->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("gyro_y"); rect = lineMatrix.mapRect(renderer->boundsOnElement("gyro_y")); startX = rect.x(); startY = rect.y()+ rect.height(); gyro_y = new QGraphicsSvgItem(); gyro_y->setSharedRenderer(renderer); gyro_y->setElementId("gyro_y"); m_ahrs->ahrsBargraph->scene()->addItem(gyro_y); gyro_y->setPos(startX,startY); gyro_y->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("gyro_z"); rect = lineMatrix.mapRect(renderer->boundsOnElement("gyro_z")); startX = rect.x(); startY = rect.y()+ rect.height(); gyro_z = new QGraphicsSvgItem(); gyro_z->setSharedRenderer(renderer); gyro_z->setElementId("gyro_z"); m_ahrs->ahrsBargraph->scene()->addItem(gyro_z); gyro_z->setPos(startX,startY); gyro_z->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("mag_x"); rect = lineMatrix.mapRect(renderer->boundsOnElement("mag_x")); startX = rect.x(); startY = rect.y()+ rect.height(); mag_x = new QGraphicsSvgItem(); mag_x->setSharedRenderer(renderer); mag_x->setElementId("mag_x"); m_ahrs->ahrsBargraph->scene()->addItem(mag_x); mag_x->setPos(startX,startY); mag_x->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("mag_y"); rect = lineMatrix.mapRect(renderer->boundsOnElement("mag_y")); startX = rect.x(); startY = rect.y()+ rect.height(); mag_y = new QGraphicsSvgItem(); mag_y->setSharedRenderer(renderer); mag_y->setElementId("mag_y"); m_ahrs->ahrsBargraph->scene()->addItem(mag_y); mag_y->setPos(startX,startY); mag_y->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("mag_z"); rect = lineMatrix.mapRect(renderer->boundsOnElement("mag_z")); startX = rect.x(); startY = rect.y()+ rect.height(); mag_z = new QGraphicsSvgItem(); mag_z->setSharedRenderer(renderer); mag_z->setElementId("mag_z"); m_ahrs->ahrsBargraph->scene()->addItem(mag_z); mag_z->setPos(startX,startY); mag_z->setTransform(QTransform::fromScale(1,0),true); position = -1; // Fill the dropdown menus: UAVObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSSettings"))); UAVObjectField *field = obj->getField(QString("Algorithm")); m_ahrs->algorithm->addItems(field->getOptions()); // Register for Home Location state changes obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("HomeLocation"))); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this , SLOT(enableHomeLocSave(UAVObject*))); // Connect the signals connect(m_ahrs->ahrsCalibStart, SIGNAL(clicked()), this, SLOT(launchAHRSCalibration())); connect(m_ahrs->ahrsSettingsRequest, SIGNAL(clicked()), this, SLOT(ahrsSettingsRequest())); /* connect(m_ahrs->algorithm, SIGNAL(currentIndexChanged(int)), this, SLOT(ahrsSettingsSave())); connect(m_ahrs->indoorFlight, SIGNAL(stateChanged(int)), this, SLOT(homeLocationSave())); connect(m_ahrs->homeLocation, SIGNAL(clicked()), this, SLOT(homeLocationSaveSD())); */ connect(m_ahrs->ahrsSettingsSaveRAM, SIGNAL(clicked()), this, SLOT(ahrsSettingsSaveRAM())); connect(m_ahrs->ahrsSettingsSaveSD, SIGNAL(clicked()), this, SLOT(ahrsSettingsSaveSD())); connect(m_ahrs->sixPointsStart, SIGNAL(clicked()), this, SLOT(sixPointCalibrationMode())); connect(m_ahrs->sixPointsSave, SIGNAL(clicked()), this, SLOT(savePositionData())); connect(parent, SIGNAL(autopilotConnected()),this, SLOT(ahrsSettingsRequest())); }
/** Request the current config from the board */ void ConfigServoWidget::requestRCInputUpdate() { UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ManualControlSettings"))); Q_ASSERT(obj); obj->requestUpdate(); UAVObjectField *field; // Now update all the slider values: UAVObjectField *field_max = obj->getField(QString("ChannelMax")); UAVObjectField *field_min = obj->getField(QString("ChannelMin")); UAVObjectField *field_neu = obj->getField(QString("ChannelNeutral")); Q_ASSERT(field_max); Q_ASSERT(field_min); Q_ASSERT(field_neu); for (int i = 0; i < 8; i++) { QVariant max = field_max->getValue(i); QVariant min = field_min->getValue(i); QVariant neutral = field_neu->getValue(i); inMaxLabels[i]->setText(max.toString()); inMinLabels[i]->setText(min.toString()); inSliders[i]->setMaximum(max.toInt()); inSliders[i]->setMinimum(min.toInt()); inSliders[i]->setValue(neutral.toInt()); } // Update receiver type field = obj->getField(QString("InputMode")); m_config->receiverType->setCurrentIndex(m_config->receiverType->findText(field->getValue().toString())); // Reset all channel assignement dropdowns: m_config->ch0Assign->setCurrentIndex(0); m_config->ch1Assign->setCurrentIndex(0); m_config->ch2Assign->setCurrentIndex(0); m_config->ch3Assign->setCurrentIndex(0); m_config->ch4Assign->setCurrentIndex(0); m_config->ch5Assign->setCurrentIndex(0); m_config->ch6Assign->setCurrentIndex(0); m_config->ch7Assign->setCurrentIndex(0); // Update all channels assignements QList<UAVObjectField *> fieldList = obj->getFields(); foreach (UAVObjectField *field, fieldList) { if (field->getUnits().contains("channel")) assignChannel(obj, field->getName()); } // Update all the flight mode settingsin the relevant tab field = obj->getField(QString("FlightModePosition")); m_config->fmsModePos1->setCurrentIndex((m_config->fmsModePos1->findText(field->getValue(0).toString()))); m_config->fmsModePos2->setCurrentIndex((m_config->fmsModePos2->findText(field->getValue(1).toString()))); m_config->fmsModePos3->setCurrentIndex((m_config->fmsModePos3->findText(field->getValue(2).toString()))); field = obj->getField(QString("Stabilization1Settings")); m_config->fmsSsPos1Roll->setCurrentIndex(m_config->fmsSsPos1Roll->findText(field->getValue(field->getElementNames().indexOf("Roll")).toString())); m_config->fmsSsPos1Pitch->setCurrentIndex(m_config->fmsSsPos1Pitch->findText(field->getValue(field->getElementNames().indexOf("Pitch")).toString())); m_config->fmsSsPos1Yaw->setCurrentIndex(m_config->fmsSsPos1Yaw->findText(field->getValue(field->getElementNames().indexOf("Yaw")).toString())); field = obj->getField(QString("Stabilization2Settings")); m_config->fmsSsPos2Roll->setCurrentIndex(m_config->fmsSsPos2Roll->findText(field->getValue(field->getElementNames().indexOf("Roll")).toString())); m_config->fmsSsPos2Pitch->setCurrentIndex(m_config->fmsSsPos2Pitch->findText(field->getValue(field->getElementNames().indexOf("Pitch")).toString())); m_config->fmsSsPos2Yaw->setCurrentIndex(m_config->fmsSsPos2Yaw->findText(field->getValue(field->getElementNames().indexOf("Yaw")).toString())); field = obj->getField(QString("Stabilization3Settings")); m_config->fmsSsPos3Roll->setCurrentIndex(m_config->fmsSsPos3Roll->findText(field->getValue(field->getElementNames().indexOf("Roll")).toString())); m_config->fmsSsPos3Pitch->setCurrentIndex(m_config->fmsSsPos3Pitch->findText(field->getValue(field->getElementNames().indexOf("Pitch")).toString())); m_config->fmsSsPos3Yaw->setCurrentIndex(m_config->fmsSsPos3Yaw->findText(field->getValue(field->getElementNames().indexOf("Yaw")).toString())); // Load the arming settings field = obj->getField(QString("Arming")); m_config->armControl->setCurrentIndex(m_config->armControl->findText(field->getValue().toString())); field = obj->getField(QString("ArmedTimeout")); m_config->armTimeout->setValue(field->getValue().toInt()/1000); }
/** * Sends the config to the board, without saving to the SD card */ void ConfigServoWidget::sendRCInputUpdate() { ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings"))); Q_ASSERT(obj); // Now update all fields from the sliders: QString fieldName = QString("ChannelMax"); UAVObjectField * field = obj->getField(fieldName); for (int i = 0; i < 8; i++) field->setValue(inMaxLabels[i]->text().toInt(), i); fieldName = QString("ChannelMin"); field = obj->getField(fieldName); for (int i = 0; i < 8; i++) field->setValue(inMinLabels[i]->text().toInt(), i); fieldName = QString("ChannelNeutral"); field = obj->getField(fieldName); for (int i = 0; i < 8; i++) field->setValue(inSliders[i]->value(), i); // Set RC Receiver type: fieldName = QString("InputMode"); field = obj->getField(fieldName); field->setValue(m_config->receiverType->currentText()); // Set Roll/Pitch/Yaw/Etc assignement: // Rule: if two channels have the same setting (which is wrong!) the higher channel // will get the setting. // First, reset all channel assignements: QList<UAVObjectField*> fieldList = obj->getFields(); foreach (UAVObjectField* field, fieldList) { if (field->getUnits().contains("channel")) { field->setValue(field->getOptions().last()); } } // Then assign according to current GUI state: if (m_config->ch0Assign->currentIndex() != 0) { field = obj->getField(m_config->ch0Assign->currentText()); field->setValue(field->getOptions().at(0)); // -> This way we don't depend on channel naming convention } if (m_config->ch1Assign->currentIndex() != 0) { field = obj->getField(m_config->ch1Assign->currentText()); field->setValue(field->getOptions().at(1)); } if (m_config->ch2Assign->currentIndex() != 0) { field = obj->getField(m_config->ch2Assign->currentText()); field->setValue(field->getOptions().at(2)); } if (m_config->ch3Assign->currentIndex() != 0) { field = obj->getField(m_config->ch3Assign->currentText()); field->setValue(field->getOptions().at(3)); } if (m_config->ch4Assign->currentIndex() != 0) { field = obj->getField(m_config->ch4Assign->currentText()); field->setValue(field->getOptions().at(4)); } if (m_config->ch5Assign->currentIndex() != 0) { field = obj->getField(m_config->ch5Assign->currentText()); field->setValue(field->getOptions().at(5)); } if (m_config->ch6Assign->currentIndex() != 0) { field = obj->getField(m_config->ch6Assign->currentText()); field->setValue(field->getOptions().at(6)); } if (m_config->ch7Assign->currentIndex() != 0) { field = obj->getField(m_config->ch7Assign->currentText()); field->setValue(field->getOptions().at(7)); } // Send all the flight mode settings field = obj->getField(QString("FlightModePosition")); field->setValue(m_config->fmsModePos1->currentText(),0); field->setValue(m_config->fmsModePos2->currentText(),1); field->setValue(m_config->fmsModePos3->currentText(),2); field = obj->getField(QString("Stabilization1Settings")); field->setValue(m_config->fmsSsPos1Roll->currentText(), field->getElementNames().indexOf("Roll")); field->setValue(m_config->fmsSsPos1Pitch->currentText(), field->getElementNames().indexOf("Pitch")); field->setValue(m_config->fmsSsPos1Yaw->currentText(), field->getElementNames().indexOf("Yaw")); field = obj->getField(QString("Stabilization2Settings")); field->setValue(m_config->fmsSsPos2Roll->currentText(), field->getElementNames().indexOf("Roll")); field->setValue(m_config->fmsSsPos2Pitch->currentText(), field->getElementNames().indexOf("Pitch")); field->setValue(m_config->fmsSsPos2Yaw->currentText(), field->getElementNames().indexOf("Yaw")); field = obj->getField(QString("Stabilization3Settings")); field->setValue(m_config->fmsSsPos3Roll->currentText(), field->getElementNames().indexOf("Roll")); field->setValue(m_config->fmsSsPos3Pitch->currentText(), field->getElementNames().indexOf("Pitch")); field->setValue(m_config->fmsSsPos3Yaw->currentText(), field->getElementNames().indexOf("Yaw")); // Save the arming settings field = obj->getField(QString("Arming")); field->setValue(m_config->armControl->currentText()); field = obj->getField(QString("ArmedTimeout")); field->setValue(m_config->armTimeout->value()*1000); // ... and send to the OP Board obj->updated(); }
/** Helper function to refresh the UI widget values */ void ConfigCustomWidget::refreshWidgetsValues(QString frameType) { Q_ASSERT(m_aircraft); setupUI(frameType); UAVDataObject *system = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("SystemSettings"))); Q_ASSERT(system); QPointer<UAVObjectField> field = system->getField(QString("AirframeType")); // Do not allow table edit until AirframeType == Custom // First save set AirframeType to 'Custom' and next modify. if (field->getValue().toString() != "Custom") { m_aircraft->customMixerTable->setEditTriggers(QAbstractItemView::NoEditTriggers); } else { m_aircraft->customMixerTable->setEditTriggers(QAbstractItemView::AllEditTriggers); } UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); getChannelDescriptions(); QList<double> curveValues; getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, &curveValues); // is at least one of the curve values != 0? if (isValidThrottleCurve(&curveValues)) { // yes, use the curve we just read from mixersettings m_aircraft->customThrottle1Curve->initCurve(&curveValues); } else { // no, init a straight curve m_aircraft->customThrottle1Curve->initLinearCurve(curveValues.count(), 1.0); } double Throttle2CurveMin = m_aircraft->customThrottle2Curve->getMin(); if (MixerSettings * mxr = qobject_cast<MixerSettings *>(mixer)) { MixerSettings::DataFields mixerSettingsData = mxr->getData(); if (mixerSettingsData.Curve2Source == MixerSettings::CURVE2SOURCE_THROTTLE && Throttle2CurveMin >= 0) { m_aircraft->customThrottle2Curve->setMixerType(MixerCurve::MIXERCURVE_THROTTLE); } else { m_aircraft->customThrottle2Curve->setMixerType(MixerCurve::MIXERCURVE_PITCH); } } // Setup all Throttle2 curves for all types of airframes getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, &curveValues); if (isValidThrottleCurve(&curveValues)) { m_aircraft->customThrottle2Curve->initCurve(&curveValues); } else { m_aircraft->customThrottle2Curve->initLinearCurve(curveValues.count(), 1.0, m_aircraft->customThrottle2Curve->getMin()); } // Update the mixer table: for (int channel = 0; channel < m_aircraft->customMixerTable->columnCount(); channel++) { UAVObjectField *field = mixer->getField(mixerTypes.at(channel)); if (field) { QComboBox *q = (QComboBox *)m_aircraft->customMixerTable->cellWidget(0, channel); if (q) { QString s = field->getValue().toString(); setComboCurrentIndex(q, q->findText(s)); } m_aircraft->customMixerTable->item(1, channel)->setText( QString::number(getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1))); m_aircraft->customMixerTable->item(2, channel)->setText( QString::number(getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2))); m_aircraft->customMixerTable->item(3, channel)->setText( QString::number(getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL))); m_aircraft->customMixerTable->item(4, channel)->setText( QString::number(getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH))); m_aircraft->customMixerTable->item(5, channel)->setText( QString::number(getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW))); } } }
/** * Updates the slider positions and min/max values * */ void ConfigServoWidget::updateChannels(UAVObject* controlCommand) { QString fieldName = QString("Connected"); UAVObjectField *field = controlCommand->getField(fieldName); if (field->getValue().toBool()) m_config->RCInputConnected->setText("RC Receiver Connected"); else m_config->RCInputConnected->setText("RC Receiver Not Connected"); if (m_config->doRCInputCalibration->isChecked()) { if (firstUpdate) { // Increase the data rate from the board so that the sliders // move faster UAVObject::Metadata mdata = controlCommand->getMetadata(); mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC; mccDataRate = mdata.flightTelemetryUpdatePeriod; mdata.flightTelemetryUpdatePeriod = 150; controlCommand->setMetadata(mdata); // Also protect the user by setting all values to zero // and making the ActuatorCommand object readonly UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorCommand"))); mdata = obj->getMetadata(); mdata.flightAccess = UAVObject::ACCESS_READONLY; obj->setMetadata(mdata); UAVObjectField *field = obj->getField("Channel"); for (int i=0; i< field->getNumElements(); i++) { field->setValue(0,i); } obj->updated(); } field = controlCommand->getField(QString("Channel")); for (int i = 0; i < 8; i++) updateChannelInSlider(inSliders[i], inMinLabels[i], inMaxLabels[i], reversals[i], field->getValue(i).toInt()); firstUpdate = false; } else { if (!firstUpdate) { // Restore original data rate from the board: UAVObject::Metadata mdata = controlCommand->getMetadata(); mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC; mdata.flightTelemetryUpdatePeriod = mccDataRate; controlCommand->setMetadata(mdata); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorCommand"))); mdata = obj->getMetadata(); mdata.flightAccess = UAVObject::ACCESS_READWRITE; obj->setMetadata(mdata); } firstUpdate = true; } //Update the Flight mode channel slider UAVObject* obj = getObjectManager()->getObject("ManualControlSettings"); // Find the channel currently assigned to flightmode field = obj->getField("FlightMode"); int chIndex = field->getOptions().indexOf(field->getValue().toString()); if (chIndex < field->getOptions().length() - 1) { float valueScaled; int chMin = inSliders[chIndex]->minimum(); int chMax = inSliders[chIndex]->maximum(); int chNeutral = inSliders[chIndex]->value(); int value = controlCommand->getField("Channel")->getValue(chIndex).toInt(); if ((chMax > chMin && value >= chNeutral) || (chMin > chMax && value <= chNeutral)) { if (chMax != chNeutral) valueScaled = (float)(value - chNeutral) / (float)(chMax - chNeutral); else valueScaled = 0; } else { if (chMin != chNeutral) valueScaled = (float)(value - chNeutral) / (float)(chNeutral - chMin); else valueScaled = 0; } // Bound if (valueScaled > 1.0) valueScaled = 1.0; else if (valueScaled < -1.0) valueScaled = -1.0; m_config->fmsSlider->setValue(valueScaled * 100); } }