MixerCurve::MixerCurve(QWidget *parent) : QFrame(parent), m_mixerUI(new Ui::MixerCurve) { m_mixerUI->setupUi(this); // setup some convienence pointers m_curve = m_mixerUI->CurveWidget; m_settings = m_mixerUI->CurveSettings; m_mixerUI->SettingsGroup->hide(); // create our spin delegate m_spinDelegate = new DoubleSpinDelegate(); // set the default mixer type setMixerType(MixerCurve::MIXERCURVE_THROTTLE); // paint the ui UpdateCurveUI(); // wire up our signals connect(m_mixerUI->CurveType, SIGNAL(currentIndexChanged(int)), this, SLOT(CurveTypeChanged())); connect(m_mixerUI->ResetCurve, SIGNAL(clicked()), this, SLOT(ResetCurve())); connect(m_mixerUI->PopupCurve, SIGNAL(clicked()), this, SLOT(PopupCurve())); connect(m_mixerUI->GenerateCurve, SIGNAL(clicked()), this, SLOT(GenerateCurve())); connect(m_curve, SIGNAL(curveUpdated()), this, SLOT(UpdateSettingsTable())); connect(m_settings, SIGNAL(cellChanged(int, int)), this, SLOT(SettingsTableChanged())); connect(m_mixerUI->CurveMin, SIGNAL(valueChanged(double)), this, SLOT(CurveMinChanged(double))); connect(m_mixerUI->CurveMax, SIGNAL(valueChanged(double)), this, SLOT(CurveMaxChanged(double))); connect(m_mixerUI->CurveStep, SIGNAL(valueChanged(double)), this, SLOT(GenerateCurve())); }
/** Setup steerable ground vehicle. Returns False if impossible to create the mixer. */ bool ConfigGroundVehicleWidget::setupGroundVehicleCar(QString airframeType) { // Check coherence: // Show any config errors in GUI if (throwConfigError(airframeType)) { return false; } // Now setup the channels: GUIConfigDataUnion config = getConfigData(); resetActuators(&config); config.ground.GroundVehicleThrottle1 = m_aircraft->gvMotor1ChannelBox->currentIndex(); config.ground.GroundVehicleThrottle2 = m_aircraft->gvMotor2ChannelBox->currentIndex(); config.ground.GroundVehicleSteering1 = m_aircraft->gvSteering1ChannelBox->currentIndex(); config.ground.GroundVehicleSteering2 = m_aircraft->gvSteering2ChannelBox->currentIndex(); setConfigData(config); UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); resetMotorAndServoMixers(mixer); int channel = m_aircraft->gvSteering1ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127); channel = m_aircraft->gvSteering2ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127); channel = m_aircraft->gvMotor1ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_REVERSABLEMOTOR); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); channel = m_aircraft->gvMotor2ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_REVERSABLEMOTOR); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); // Output success message m_aircraft->gvStatusLabel->setText("Mixer generated"); return true; }
/** Setup steerable ground vehicle. Returns False if impossible to create the mixer. */ bool ConfigGroundVehicleWidget::setupGroundVehicleCar(SystemSettings::AirframeTypeOptions airframeType) { // Check coherence: //Show any config errors in GUI if (throwConfigError(airframeType)) { return false; } // Now setup the channels: GUIConfigDataUnion config = GetConfigData(); ResetActuators(&config); config.ground.GroundVehicleThrottle1 = m_aircraft->gvMotor1ChannelBox->currentIndex(); config.ground.GroundVehicleThrottle2 = m_aircraft->gvMotor2ChannelBox->currentIndex(); config.ground.GroundVehicleSteering1 = m_aircraft->gvSteering1ChannelBox->currentIndex(); config.ground.GroundVehicleSteering2 = m_aircraft->gvSteering2ChannelBox->currentIndex(); SetConfigData(config); MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager()); Q_ASSERT(mixerSettings); resetMixers(mixerSettings); int channel = m_aircraft->gvSteering1ChannelBox->currentIndex()-1; setMixerType(mixerSettings,channel, MixerSettings::MIXER1TYPE_SERVO); setMixerVectorValue(mixerSettings, channel, MixerSettings::MIXER1VECTOR_YAW, 127); channel = m_aircraft->gvSteering2ChannelBox->currentIndex()-1; setMixerType(mixerSettings,channel, MixerSettings::MIXER1TYPE_SERVO); setMixerVectorValue(mixerSettings, channel, MixerSettings::MIXER1VECTOR_YAW, -127); channel = m_aircraft->gvMotor1ChannelBox->currentIndex()-1; setMixerType(mixerSettings,channel, MixerSettings::MIXER1TYPE_MOTOR); setMixerVectorValue(mixerSettings, channel, MixerSettings::MIXER1VECTOR_THROTTLECURVE1, 127); channel = m_aircraft->gvMotor2ChannelBox->currentIndex()-1; setMixerType(mixerSettings,channel, MixerSettings::MIXER1TYPE_MOTOR); setMixerVectorValue(mixerSettings, channel, MixerSettings::MIXER1VECTOR_THROTTLECURVE2, 127); //Output success message m_aircraft->gvStatusLabel->setText("Mixer generated"); return true; }
/** Helper function: setupQuadMotor */ void ConfigMultiRotorWidget::setupQuadMotor(int channel, double pitch, double roll, double yaw) { MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager()); Q_ASSERT(mixerSettings); setMixerType(mixerSettings, channel, MixerSettings::MIXER1TYPE_MOTOR); setMixerVectorValue(mixerSettings, channel, MixerSettings::MIXER1VECTOR_THROTTLECURVE1, 127); setMixerVectorValue(mixerSettings, channel, MixerSettings::MIXER1VECTOR_THROTTLECURVE2, 0); setMixerVectorValue(mixerSettings, channel, MixerSettings::MIXER1VECTOR_ROLL, roll*127); setMixerVectorValue(mixerSettings, channel, MixerSettings::MIXER1VECTOR_PITCH, pitch*127); setMixerVectorValue(mixerSettings, channel, MixerSettings::MIXER1VECTOR_YAW, yaw*127); }
MixerCurve::MixerCurve(QWidget *parent) : QFrame(parent), m_mixerUI(new Ui::MixerCurvePlot) { m_mixerUI->setupUi(this); // setup some convienence pointers m_curve = m_mixerUI->CurveWidget; m_settings = m_mixerUI->CurveSettings; // by default mixcurve isn't used for curve2source m_mixerUI->CBCurve2Source->hide(); m_mixerUI->SettingsGroup->hide(); m_curve->showCommands(false); m_curve->showCommand("Reset", false); m_curve->showCommand("Popup", false); m_curve->showCommand("Commands", false); // create our spin delegate m_spinDelegate = new DoubleSpinDelegate(); // set the default mixer type setMixerType(MixerCurve::MIXERCURVE_THROTTLE); // setup and turn off advanced mode CommandActivated(); // paint the ui UpdateCurveUI(); // wire up our signals connect(m_mixerUI->CurveType, SIGNAL(currentIndexChanged(int)), this, SLOT(CurveTypeChanged())); connect(m_mixerUI->ResetCurve, SIGNAL(clicked()), this, SLOT(ResetCurve())); connect(m_mixerUI->PopupCurve, SIGNAL(clicked()),this,SLOT(PopupCurve())); connect(m_mixerUI->GenerateCurve, SIGNAL(clicked()), this, SLOT(GenerateCurve())); connect(m_curve, SIGNAL(curveUpdated()), this, SLOT(UpdateSettingsTable())); connect(m_curve, SIGNAL(commandActivated(MixerNode*)),this, SLOT(CommandActivated(MixerNode*))); connect(m_settings, SIGNAL(cellChanged(int,int)), this, SLOT(SettingsTableChanged())); connect(m_mixerUI->CurveMin, SIGNAL(valueChanged(double)), this, SLOT(CurveMinChanged(double))); connect(m_mixerUI->CurveMax, SIGNAL(valueChanged(double)), this, SLOT(CurveMaxChanged(double))); connect(m_mixerUI->CurveStep, SIGNAL(valueChanged(double)), this, SLOT(GenerateCurve())); }
/** Helper function to */ QString ConfigCustomWidget::updateConfigObjectsFromWidgets() { UAVDataObject *system = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("SystemSettings"))); Q_ASSERT(system); QPointer<UAVObjectField> field = system->getField(QString("AirframeType")); // Do not allow changes until AirframeType == Custom // If user want to save custom mixer : first set AirframeType to 'Custom' without changes and next modify. if (field->getValue().toString() == "Custom") { UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->customThrottle1Curve->getCurve()); setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, m_aircraft->customThrottle2Curve->getCurve()); GUIConfigDataUnion configData = getConfigData(); resetActuators(&configData); // Update the table: for (int channel = 0; channel < (int)VehicleConfig::CHANNEL_NUMELEM; channel++) { QComboBox *q = (QComboBox *)m_aircraft->customMixerTable->cellWidget(0, channel); if (q->currentText() == "Disabled") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_DISABLED); } else if (q->currentText() == "Motor") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_MOTOR); if (configData.custom.Motor1 == 0) { configData.custom.Motor1 = channel + 1; } else if (configData.custom.Motor2 == 0) { configData.custom.Motor2 = channel + 1; } else if (configData.custom.Motor3 == 0) { configData.custom.Motor3 = channel + 1; } else if (configData.custom.Motor4 == 0) { configData.custom.Motor4 = channel + 1; } else if (configData.custom.Motor5 == 0) { configData.custom.Motor5 = channel + 1; } else if (configData.custom.Motor6 == 0) { configData.custom.Motor6 = channel + 1; } else if (configData.custom.Motor7 == 0) { configData.custom.Motor7 = channel + 1; } else if (configData.custom.Motor8 == 0) { configData.custom.Motor8 = channel + 1; } } else if (q->currentText() == "ReversableMotor") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_REVERSABLEMOTOR); if (configData.custom.RevMotor1 == 0) { configData.custom.RevMotor1 = channel + 1; } else if (configData.custom.RevMotor2 == 0) { configData.custom.RevMotor2 = channel + 1; } else if (configData.custom.RevMotor3 == 0) { configData.custom.RevMotor3 = channel + 1; } else if (configData.custom.RevMotor4 == 0) { configData.custom.RevMotor4 = channel + 1; } else if (configData.custom.RevMotor5 == 0) { configData.custom.RevMotor5 = channel + 1; } else if (configData.custom.RevMotor6 == 0) { configData.custom.RevMotor6 = channel; } else if (configData.custom.RevMotor7 == 0) { configData.custom.RevMotor7 = channel; } else if (configData.custom.RevMotor8 == 0) { configData.custom.RevMotor8 = channel; } } else if (q->currentText() == "Servo") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); if (configData.custom.Servo1 == 0) { configData.custom.Servo1 = channel + 1; } else if (configData.custom.Servo2 == 0) { configData.custom.Servo2 = channel + 1; } else if (configData.custom.Servo3 == 0) { configData.custom.Servo3 = channel + 1; } else if (configData.custom.Servo4 == 0) { configData.custom.Servo4 = channel + 1; } else if (configData.custom.Servo5 == 0) { configData.custom.Servo5 = channel + 1; } else if (configData.custom.Servo6 == 0) { configData.custom.Servo6 = channel + 1; } else if (configData.custom.Servo7 == 0) { configData.custom.Servo7 = channel + 1; } else if (configData.custom.Servo8 == 0) { configData.custom.Servo8 = channel + 1; } } else if (q->currentText() == "CameraRoll") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_CAMERAROLL); } else if (q->currentText() == "CameraPitch") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_CAMERAPITCH); } else if (q->currentText() == "CameraYaw") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_CAMERAYAW); } else if (q->currentText() == "Accessory0") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY0); } else if (q->currentText() == "Accessory1") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY1); } else if (q->currentText() == "Accessory2") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY2); } else if (q->currentText() == "Accessory3") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY3); } else if (q->currentText() == "Accessory4") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY4); } else if (q->currentText() == "Accessory5") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY5); } setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, m_aircraft->customMixerTable->item(1, channel)->text().toDouble()); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, m_aircraft->customMixerTable->item(2, channel)->text().toDouble()); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, m_aircraft->customMixerTable->item(3, channel)->text().toDouble()); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, m_aircraft->customMixerTable->item(4, channel)->text().toDouble()); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, m_aircraft->customMixerTable->item(5, channel)->text().toDouble()); } setConfigData(configData); } return "Custom"; }
/** Helper function to */ QString ConfigCustomWidget::updateConfigObjectsFromWidgets() { UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->customThrottle1Curve->getCurve()); setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, m_aircraft->customThrottle2Curve->getCurve()); // Update the table: for (int channel = 0; channel < (int)VehicleConfig::CHANNEL_NUMELEM; channel++) { QComboBox *q = (QComboBox *)m_aircraft->customMixerTable->cellWidget(0, channel); if (q->currentText() == "Disabled") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_DISABLED); } else if (q->currentText() == "Motor") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_MOTOR); } else if (q->currentText() == "ReversableMotor") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_REVERSABLEMOTOR); } else if (q->currentText() == "Servo") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); } else if (q->currentText() == "CameraRoll") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_CAMERAROLL); } else if (q->currentText() == "CameraPitch") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_CAMERAPITCH); } else if (q->currentText() == "CameraYaw") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_CAMERAYAW); } else if (q->currentText() == "Accessory0") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY0); } else if (q->currentText() == "Accessory1") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY1); } else if (q->currentText() == "Accessory2") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY2); } else if (q->currentText() == "Accessory3") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY3); } else if (q->currentText() == "Accessory4") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY4); } else if (q->currentText() == "Accessory5") { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY5); } setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, m_aircraft->customMixerTable->item(1, channel)->text().toDouble()); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, m_aircraft->customMixerTable->item(2, channel)->text().toDouble()); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, m_aircraft->customMixerTable->item(3, channel)->text().toDouble()); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, m_aircraft->customMixerTable->item(4, channel)->text().toDouble()); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, m_aircraft->customMixerTable->item(5, channel)->text().toDouble()); } return "Custom"; }
/** Setup VTail */ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType) { // Check coherence: // Show any config errors in GUI if (throwConfigError(airframeType)) { return false; } GUIConfigDataUnion config = getConfigData(); resetActuators(&config); config.fixedwing.FixedWingPitch1 = m_aircraft->fwElevator1ChannelBox->currentIndex(); config.fixedwing.FixedWingPitch2 = m_aircraft->fwElevator2ChannelBox->currentIndex(); config.fixedwing.FixedWingRoll1 = m_aircraft->fwAileron1ChannelBox->currentIndex(); config.fixedwing.FixedWingRoll2 = m_aircraft->fwAileron2ChannelBox->currentIndex(); config.fixedwing.FixedWingThrottle = m_aircraft->fwEngineChannelBox->currentIndex(); setConfigData(config); UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); resetMotorAndServoMixers(mixer); // Save the curve: // ... and compute the matrix: // In order to make code a bit nicer, we assume: // - Channel dropdowns start with 'None', then 0 to 7 // 1. Assign the servo/motor/none for each channel double pitch; double roll; double yaw; // motor int channel = m_aircraft->fwEngineChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_MOTOR); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); // ailerons setMixerValue(mixer, "FirstRollServo", m_aircraft->fwAileron1ChannelBox->currentIndex()); channel = m_aircraft->fwAileron1ChannelBox->currentIndex() - 1; if (channel > -1) { // Roll mixer value, currently no slider (should be added for Ailerons response ?) roll = 127; // Store Roll fixed and RollDifferential values onboard setMixerValue(mixer, "MixerValueRoll", 100); setMixerValue(mixer, "RollDifferential", m_aircraft->elevonSlider3->value()); // First Aileron (left) setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, roll); // Second Aileron (right) channel = m_aircraft->fwAileron2ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, roll); } // vtail (pitch / yaw mixing) channel = m_aircraft->fwElevator1ChannelBox->currentIndex() - 1; if (channel > -1) { // Compute mixer absolute values pitch = (double)(m_aircraft->elevonSlider2->value() * 1.27); yaw = (double)(m_aircraft->elevonSlider1->value() * 1.27); // Store sliders values onboard setMixerValue(mixer, "MixerValuePitch", m_aircraft->elevonSlider2->value()); setMixerValue(mixer, "MixerValueYaw", m_aircraft->elevonSlider1->value()); // First Vtail servo setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, -pitch); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -yaw); // Second Vtail servo channel = m_aircraft->fwElevator2ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, pitch); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -yaw); } m_aircraft->fwStatusLabel->setText("Mixer generated"); return true; }
/** Setup Elevator/Aileron/Rudder airframe. If both Aileron channels are set to 'None' (EasyStar), do Pitch/Rudder mixing Returns False if impossible to create the mixer. */ bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType) { // Check coherence: // Show any config errors in GUI if (throwConfigError(airframeType)) { return false; } // Now setup the channels: GUIConfigDataUnion config = getConfigData(); resetActuators(&config); config.fixedwing.FixedWingPitch1 = m_aircraft->fwElevator1ChannelBox->currentIndex(); config.fixedwing.FixedWingPitch2 = m_aircraft->fwElevator2ChannelBox->currentIndex(); config.fixedwing.FixedWingRoll1 = m_aircraft->fwAileron1ChannelBox->currentIndex(); config.fixedwing.FixedWingRoll2 = m_aircraft->fwAileron2ChannelBox->currentIndex(); config.fixedwing.FixedWingYaw1 = m_aircraft->fwRudder1ChannelBox->currentIndex(); config.fixedwing.FixedWingYaw2 = m_aircraft->fwRudder2ChannelBox->currentIndex(); config.fixedwing.FixedWingThrottle = m_aircraft->fwEngineChannelBox->currentIndex(); setConfigData(config); UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); resetMotorAndServoMixers(mixer); // ... and compute the matrix: // In order to make code a bit nicer, we assume: // - Channel dropdowns start with 'None', then 0 to 7 // 1. Assign the servo/motor/none for each channel // motor int channel = m_aircraft->fwEngineChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_MOTOR); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); // rudder channel = m_aircraft->fwRudder1ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127); // ailerons setMixerValue(mixer, "FirstRollServo", m_aircraft->fwAileron1ChannelBox->currentIndex()); channel = m_aircraft->fwAileron1ChannelBox->currentIndex() - 1; if (channel > -1) { // Store differential value onboard setMixerValue(mixer, "RollDifferential", m_aircraft->elevonSlider3->value()); setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, 127); channel = m_aircraft->fwAileron2ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, 127); } // elevators channel = m_aircraft->fwElevator1ChannelBox->currentIndex() - 1; if (channel > -1) { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, 127); channel = m_aircraft->fwElevator2ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, 127); } m_aircraft->fwStatusLabel->setText("Mixer generated"); return true; }
/** Helper function to update the UI widget objects */ SystemSettings::AirframeTypeOptions ConfigMultiRotorWidget::updateConfigObjectsFromWidgets() { SystemSettings::AirframeTypeOptions airframeType = SystemSettings::AIRFRAMETYPE_FIXEDWING; QList<QString> motorList; MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager()); Q_ASSERT(mixerSettings); // Curve is also common to all quads: setThrottleCurve(mixerSettings, MixerSettings::MIXER1VECTOR_THROTTLECURVE1, m_aircraft->multiThrottleCurve->getCurve() ); if (m_aircraft->multirotorFrameType->itemData(m_aircraft->multirotorFrameType->currentIndex()) == SystemSettings::AIRFRAMETYPE_QUADP) { airframeType = SystemSettings::AIRFRAMETYPE_QUADP; setupQuad(true); } else if (m_aircraft->multirotorFrameType->itemData(m_aircraft->multirotorFrameType->currentIndex()) == SystemSettings::AIRFRAMETYPE_QUADX) { airframeType = SystemSettings::AIRFRAMETYPE_QUADX; setupQuad(false); } else if (m_aircraft->multirotorFrameType->itemData(m_aircraft->multirotorFrameType->currentIndex()) == SystemSettings::AIRFRAMETYPE_HEXA) { airframeType = SystemSettings::AIRFRAMETYPE_HEXA; setupHexa(true); } else if (m_aircraft->multirotorFrameType->itemData(m_aircraft->multirotorFrameType->currentIndex()) == SystemSettings::AIRFRAMETYPE_HEXAX) { airframeType = SystemSettings::AIRFRAMETYPE_HEXAX; setupHexa(false); } else if (m_aircraft->multirotorFrameType->itemData(m_aircraft->multirotorFrameType->currentIndex()) == SystemSettings::AIRFRAMETYPE_HEXACOAX) { airframeType = SystemSettings::AIRFRAMETYPE_HEXACOAX; //Show any config errors in GUI if (throwConfigError(6)) { return airframeType; } motorList << "VTOLMotorNW" << "VTOLMotorW" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorS" << "VTOLMotorSE"; setupMotors(motorList); // Motor 1 to 6, Y6 Layout: // pitch roll yaw double mixer [8][3] = { { 0.5, 1, -1}, { 0.5, 1, 1}, { 0.5, -1, -1}, { 0.5, -1, 1}, { -1, 0, -1}, { -1, 0, 1}, { 0, 0, 0}, { 0, 0, 0} }; setupMultiRotorMixer(mixer); m_aircraft->mrStatusLabel->setText("Configuration OK"); } else if (m_aircraft->multirotorFrameType->itemData(m_aircraft->multirotorFrameType->currentIndex()) == SystemSettings::AIRFRAMETYPE_OCTO) { airframeType = SystemSettings::AIRFRAMETYPE_OCTO; //Show any config errors in GUI if (throwConfigError(8)) { return airframeType; } motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW"; setupMotors(motorList); // Motor 1 to 8: // pitch roll yaw double mixer [8][3] = { { 1, 0, -1}, { 1, -1, 1}, { 0, -1, -1}, { -1, -1, 1}, { -1, 0, -1}, { -1, 1, 1}, { 0, 1, -1}, { 1, 1, 1} }; setupMultiRotorMixer(mixer); m_aircraft->mrStatusLabel->setText("Configuration OK"); } else if (m_aircraft->multirotorFrameType->itemData(m_aircraft->multirotorFrameType->currentIndex()) == SystemSettings::AIRFRAMETYPE_OCTOV) { airframeType = SystemSettings::AIRFRAMETYPE_OCTOV; //Show any config errors in GUI if (throwConfigError(8)) { return airframeType; } motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW"; setupMotors(motorList); // Motor 1 to 8: // IMPORTANT: Assumes evenly spaced engines // pitch roll yaw double mixer [8][3] = { { 0.33, -1, -1}, { 1 , -1, 1}, { -1 , -1, -1}, { -0.33, -1, 1}, { -0.33, 1, -1}, { -1 , 1, 1}, { 1 , 1, -1}, { 0.33, 1, 1} }; setupMultiRotorMixer(mixer); m_aircraft->mrStatusLabel->setText("Configuration OK"); } else if (m_aircraft->multirotorFrameType->itemData(m_aircraft->multirotorFrameType->currentIndex()) == SystemSettings::AIRFRAMETYPE_OCTOCOAXP) { airframeType = SystemSettings::AIRFRAMETYPE_OCTOCOAXP; //Show any config errors in GUI if (throwConfigError(8)) { return airframeType; } motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW"; setupMotors(motorList); // Motor 1 to 8: // pitch roll yaw double mixer [8][3] = { { 1, 0, -1}, { 1, 0, 1}, { 0, -1, -1}, { 0, -1, 1}, { -1, 0, -1}, { -1, 0, 1}, { 0, 1, -1}, { 0, 1, 1} }; setupMultiRotorMixer(mixer); m_aircraft->mrStatusLabel->setText("Configuration OK"); } else if (m_aircraft->multirotorFrameType->itemData(m_aircraft->multirotorFrameType->currentIndex()) == SystemSettings::AIRFRAMETYPE_OCTOCOAXX) { airframeType = SystemSettings::AIRFRAMETYPE_OCTOCOAXX; //Show any config errors in GUI if (throwConfigError(8)) { return airframeType; } motorList << "VTOLMotorNW" << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW"; setupMotors(motorList); // Motor 1 to 8: // pitch roll yaw double mixer [8][3] = { { 1, 1, -1}, { 1, 1, 1}, { 1, -1, -1}, { 1, -1, 1}, { -1, -1, -1}, { -1, -1, 1}, { -1, 1, -1}, { -1, 1, 1} }; setupMultiRotorMixer(mixer); m_aircraft->mrStatusLabel->setText("Configuration OK"); } else if (m_aircraft->multirotorFrameType->itemData(m_aircraft->multirotorFrameType->currentIndex()) == SystemSettings::AIRFRAMETYPE_TRI) { airframeType = SystemSettings::AIRFRAMETYPE_TRI; //Show any config errors in GUI if (throwConfigError(3)) { return airframeType; } if (m_aircraft->triYawChannelBox->currentText() == "None") { m_aircraft->mrStatusLabel->setText("<font color='red'>Error: Assign a Yaw channel</font>"); return airframeType; } motorList << "VTOLMotorNW" << "VTOLMotorNE" << "VTOLMotorS"; setupMotors(motorList); GUIConfigDataUnion config = GetConfigData(); config.multi.TRIYaw = m_aircraft->triYawChannelBox->currentIndex(); SetConfigData(config); // Motor 1 to 6, Y6 Layout: // pitch roll yaw double mixer [8][3] = { { 0.5, 1, 0}, { 0.5, -1, 0}, { -1, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0} }; setupMultiRotorMixer(mixer); //tell the mixer about tricopter yaw channel int channel = m_aircraft->triYawChannelBox->currentIndex()-1; if (channel > -1) { setMixerType(mixerSettings, channel, MixerSettings::MIXER1TYPE_SERVO); setMixerVectorValue(mixerSettings, channel, MixerSettings::MIXER1VECTOR_YAW, 127); } m_aircraft->mrStatusLabel->setText(tr("Configuration OK")); } return airframeType; }