/** Virtual function to update the UI widget objects */ QString ConfigGroundVehicleWidget::updateConfigObjectsFromWidgets() { QString airframeType = "GroundVehicleCar"; // Save the curve (common to all ground vehicle frames) UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings"))); // Remove Feed Forward, it is pointless on a ground vehicle: setMixerValue(mixer, "FeedForward", 0.0); // set the throttle curves setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->groundVehicleThrottle1->getCurve()); setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, m_aircraft->groundVehicleThrottle2->getCurve()); // All airframe types must start with "GroundVehicle" if (m_aircraft->groundVehicleType->currentText() == "Turnable (car)") { airframeType = "GroundVehicleCar"; setupGroundVehicleCar(airframeType); } else if (m_aircraft->groundVehicleType->currentText() == "Differential (tank)") { airframeType = "GroundVehicleDifferential"; setupGroundVehicleDifferential(airframeType); } else { // "Motorcycle" airframeType = "GroundVehicleMotorcycle"; setupGroundVehicleMotorcycle(airframeType); } return airframeType; }
/** * @brief ConfigFixedWingWidget::updateConfigObjectsFromWidgets update the UI widget objects * @return airframe type */ SystemSettings::AirframeTypeOptions ConfigGroundVehicleWidget::updateConfigObjectsFromWidgets() { SystemSettings::AirframeTypeOptions airframeType = SystemSettings::AIRFRAMETYPE_GROUNDVEHICLECAR; // Save the curve (common to all ground vehicle frames) MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager()); Q_ASSERT(mixerSettings); // Remove Feed Forward, it is pointless on a ground vehicle: setMixerValue(mixerSettings, "FeedForward", 0.0); // set the throttle curves setThrottleCurve(mixerSettings, MixerSettings::MIXER1VECTOR_THROTTLECURVE1, m_aircraft->groundVehicleThrottle1->getCurve() ); setThrottleCurve(mixerSettings, MixerSettings::MIXER1VECTOR_THROTTLECURVE2, m_aircraft->groundVehicleThrottle2->getCurve() ); //All airframe types must start with "GroundVehicle" if (m_aircraft->groundVehicleType->currentText() == "Turnable (car)" ) { airframeType = SystemSettings::AIRFRAMETYPE_GROUNDVEHICLECAR; setupGroundVehicleCar(airframeType); } else if (m_aircraft->groundVehicleType->currentText() == "Differential (tank)") { airframeType = SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEDIFFERENTIAL; setupGroundVehicleDifferential(airframeType); } else { // "Motorcycle" airframeType = SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEMOTORCYCLE; setupGroundVehicleMotorcycle(airframeType); } return airframeType; }
/* * Parse the audio configuration file. * The file is named audio_conf.txt and must begin with the following header: * * card=<ALSA card number> * device=<ALSA device number> * period_size=<period size> * period_count=<period count> * * This header is followed by zero or more mixer settings, each with the format: * mixer "<name>" = <value list> * Since mixer names can contain spaces, the name must be enclosed in double quotes. * The values in the value list can be integers, booleans (represented by 0 or 1) * or strings for enum values. */ bool AudioPlayer::init(const char* config) { int tempInt; struct mixer* mixer = NULL; char name[MAX_LINE_LENGTH]; for (;;) { const char* endl = strstr(config, "\n"); if (!endl) break; String8 line(config, endl - config); if (line.length() >= MAX_LINE_LENGTH) { ALOGE("Line too long in audio_conf.txt"); return false; } const char* l = line.string(); if (sscanf(l, "card=%d", &tempInt) == 1) { ALOGD("card=%d", tempInt); mCard = tempInt; mixer = mixer_open(mCard); if (!mixer) { ALOGE("could not open mixer for card %d", mCard); return false; } } else if (sscanf(l, "device=%d", &tempInt) == 1) { ALOGD("device=%d", tempInt); mDevice = tempInt; } else if (sscanf(l, "period_size=%d", &tempInt) == 1) { ALOGD("period_size=%d", tempInt); mPeriodSize = tempInt; } else if (sscanf(l, "period_count=%d", &tempInt) == 1) { ALOGD("period_count=%d", tempInt); mPeriodCount = tempInt; } else if (sscanf(l, "mixer \"%[0-9a-zA-Z _]s\"", name) == 1) { const char* values = strchr(l, '='); if (values) { values++; // skip '=' ALOGD("name: \"%s\" = %s", name, values); setMixerValue(mixer, name, values); } else { ALOGE("values missing for name: \"%s\"", name); } } config = ++endl; } mixer_close(mixer); if (mCard >= 0 && mDevice >= 0) { return true; } return false; }
/** 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; }