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")); }
/*! \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); }
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"); }
/** 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); }
/** 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(); }
/** 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(); }
// 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); } }
/** * 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); } }
/** * 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(); }
/** * 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(); }