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); } }
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")); }
/* * This overridden function refreshes widgets which have no direct relation * to any of UAVObjects. It saves their dirty state first because update comes * from UAVObjects, and then restores it. Aftewards it calls base class * function to take care of other widgets which were dynamically added. */ void ConfigCameraStabilizationWidget::refreshWidgetsValues(UAVObject *obj) { bool dirty = isDirty(); // Set module enable checkbox from OptionalModules UAVObject item. // It needs special processing because ConfigTaskWidget uses TRUE/FALSE // for QCheckBox, but OptionalModules uses Enabled/Disabled enum values. HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); HwSettings::DataFields hwSettingsData = hwSettings->getData(); ui->enableCameraStabilization->setChecked( hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] == HwSettings::OPTIONALMODULES_ENABLED); // Load mixer outputs which are mapped to camera controls MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager()); MixerSettings::DataFields mixerSettingsData = mixerSettings->getData(); // TODO: Need to reformat object so types are an // array themselves. This gets really awkward quint8 *mixerTypes[] = { &mixerSettingsData.Mixer1Type, &mixerSettingsData.Mixer2Type, &mixerSettingsData.Mixer3Type, &mixerSettingsData.Mixer4Type, &mixerSettingsData.Mixer5Type, &mixerSettingsData.Mixer6Type, &mixerSettingsData.Mixer7Type, &mixerSettingsData.Mixer8Type, &mixerSettingsData.Mixer9Type, &mixerSettingsData.Mixer10Type, }; const int NUM_MIXERS = sizeof(mixerTypes) / sizeof(mixerTypes[0]); QComboBox *outputs[] = { ui->rollChannel, ui->pitchChannel, ui->yawChannel }; const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]); for (int i = 0; i < NUM_OUTPUTS; i++) { // Default to none if not found. // Then search for any mixer channels set to this outputs[i]->setCurrentIndex(0); for (int j = 0; j < NUM_MIXERS; j++) { if (*mixerTypes[j] == (MixerSettings::MIXER1TYPE_CAMERAROLLORSERVO1 + i) && outputs[i]->currentIndex() != (j + 1)) { outputs[i]->setCurrentIndex(j + 1); } } } setDirty(dirty); ConfigTaskWidget::refreshWidgetsValues(obj); }
/** * Create a clone of this object, a new instance ID must be specified. * Do not use this function directly to create new instances, the * UAVObjectManager should be used instead. */ UAVDataObject* MixerSettings::clone(quint32 instID) { MixerSettings* obj = new MixerSettings(); obj->initialize(instID, this->getMetaObject()); return obj; }
/* * This overridden function updates UAVObjects which have no direct relation * to any of widgets. Aftewards it calls base class function to take care of * other object to widget relations which were dynamically added. */ void ConfigCameraStabilizationWidget::updateObjectsFromWidgets() { // Save state of the module enable checkbox first. // Do not use setData() member on whole object, if possible, since it triggers // unnessesary UAVObect update. quint8 enableModule = ui->enableCameraStabilization->isChecked() ? HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED; HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_CAMERASTAB, enableModule); // Update mixer channels which were mapped to camera outputs in case they are // not used for other function yet MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager()); MixerSettings::DataFields mixerSettingsData = mixerSettings->getData(); // TODO: Need to reformat object so types are an // array themselves. This gets really awkward quint8 *mixerTypes[] = { &mixerSettingsData.Mixer1Type, &mixerSettingsData.Mixer2Type, &mixerSettingsData.Mixer3Type, &mixerSettingsData.Mixer4Type, &mixerSettingsData.Mixer5Type, &mixerSettingsData.Mixer6Type, &mixerSettingsData.Mixer7Type, &mixerSettingsData.Mixer8Type, &mixerSettingsData.Mixer9Type, &mixerSettingsData.Mixer10Type, }; const int NUM_MIXERS = sizeof(mixerTypes) / sizeof(mixerTypes[0]); QComboBox *outputs[] = { ui->rollChannel, ui->pitchChannel, ui->yawChannel }; const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]); ui->message->setText(""); bool widgetUpdated; do { widgetUpdated = false; for (int i = 0; i < NUM_OUTPUTS; i++) { // Channel 1 is second entry, so becomes zero int mixerNum = outputs[i]->currentIndex() - 1; if ((mixerNum >= 0) && // Short circuit in case of none (*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_DISABLED) && (*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_CAMERAROLLORSERVO1 + i)) { // If the mixer channel already mapped to something, it should not be // used for camera output, we reset it to none outputs[i]->setCurrentIndex(0); ui->message->setText("One of the channels is already assigned, reverted to none"); // Loop again or we may have inconsistent widget and UAVObject widgetUpdated = true; } else { // Make sure no other channels have this output set for (int j = 0; j < NUM_MIXERS; j++) { if (*mixerTypes[j] == (MixerSettings::MIXER1TYPE_CAMERAROLLORSERVO1 + i)) { *mixerTypes[j] = MixerSettings::MIXER1TYPE_DISABLED; } } // If this channel is assigned to one of the outputs that is not disabled // set it if ((mixerNum >= 0) && (mixerNum < NUM_MIXERS)) { *mixerTypes[mixerNum] = MixerSettings::MIXER1TYPE_CAMERAROLLORSERVO1 + i; } } } } while (widgetUpdated); // FIXME: Should not use setData() to prevent double updates. // It should be refactored after the reformatting of MixerSettings UAVObject. mixerSettings->setData(mixerSettingsData); ConfigTaskWidget::updateObjectsFromWidgets(); }