diff --git a/ground/openpilotgcs/src/plugins/config/airframe.ui b/ground/openpilotgcs/src/plugins/config/airframe.ui
index 620faf6c5..47006a789 100644
--- a/ground/openpilotgcs/src/plugins/config/airframe.ui
+++ b/ground/openpilotgcs/src/plugins/config/airframe.ui
@@ -6,8 +6,8 @@
0
0
- 730
- 602
+ 796
+ 618
@@ -74,7 +74,7 @@
-
- 1
+ 0
diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.cpp b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.cpp
index 10b1d6bbf..a7e46eb83 100644
--- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.cpp
+++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.cpp
@@ -25,7 +25,6 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "configccpmwidget.h"
-//#include "mixersettings.h"
#include
#include
@@ -555,7 +554,7 @@ void ConfigCcpmWidget::updateThrottleCurveValue(QList curveValues0,doubl
for (i=0; iCurveSettings->item(i, 1 )->text().toDouble();
+ CurrentValue=m_ccpm->CurveSettings->item(i, 0 )->text().toDouble();
if (CurrentValue!=internalCurveValues[i])
{
m_ccpm->CurveSettings->item(i, 0)->setText(QString().sprintf("%.3f",internalCurveValues.at(i)));
@@ -1225,11 +1224,10 @@ void ConfigCcpmWidget::setMixer()
}
//get the user data for the curve into the mixer settings
- for (i=0;i<5;i++)
+ for (i=0;i<5;i++) {
mixerSettingsData.ThrottleCurve1[i] = m_ccpm->CurveSettings->item(i, 0)->text().toDouble();
-
- for (i=0;i<5;i++)
mixerSettingsData.ThrottleCurve2[i] = m_ccpm->CurveSettings->item(i, 1)->text().toDouble();
+ }
//mapping of collective input to curve 2...
//MixerSettings.Curve2Source = Throttle,Roll,Pitch,Yaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5
diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp
index b1354a447..cbb7f94cf 100644
--- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp
+++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp
@@ -182,18 +182,16 @@ QString ConfigFixedWingWidget::updateConfigObjectsFromWidgets()
QString airframeType = "FixedWing";
// Save the curve (common to all Fixed wing frames)
- UAVDataObject *obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings")));
-
+ UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings")));
+ Q_ASSERT(mixer);
+
// Remove Feed Forward, it is pointless on a plane:
- UAVObjectField* field = obj->getField(QString("FeedForward"));
+ UAVObjectField* field = mixer->getField(QString("FeedForward"));
field->setDouble(0);
- field = obj->getField("ThrottleCurve1");
- QList curve = m_aircraft->fixedWingThrottle->getCurve();
- for (int i=0;isetValue(curve.at(i),i);
- }
-
+ // Set the throttle curve
+ setThrottleCurve(mixer,VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->fixedWingThrottle->getCurve());
+
//All airframe types must start with "FixedWing"
if (m_aircraft->fixedWingType->currentText() == "Elevator aileron rudder" ) {
airframeType = "FixedWing";
@@ -229,36 +227,26 @@ void ConfigFixedWingWidget::refreshWidgetsValues(QString frameType)
setComboCurrentIndex(m_aircraft->fwRudder1ChannelBox, fixed.FixedWingYaw1);
setComboCurrentIndex(m_aircraft->fwRudder2ChannelBox, fixed.FixedWingYaw2);
- UAVDataObject* obj;
- UAVObjectField *field;
+ UAVDataObject* mixer= dynamic_cast(getObjectManager()->getObject(QString("MixerSettings")));
+ Q_ASSERT(mixer);
+ int channel;
if (frameType == "FixedWingElevon") {
// If the airframe is elevon, restore the slider setting
- // Find the channel number for Elevon1 (FixedWingRoll1)
- obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings")));
- Q_ASSERT(obj);
- int chMixerNumber = m_aircraft->fwAileron1ChannelBox->currentIndex()-1;
- if (chMixerNumber >= 0) { // If for some reason the actuators were incoherent, we might fail here, hence the check.
- field = obj->getField(mixerVectors.at(chMixerNumber));
- int ti = field->getElementNames().indexOf("Roll");
- m_aircraft->elevonSlider1->setValue(field->getDouble(ti)*100);
- ti = field->getElementNames().indexOf("Pitch");
- m_aircraft->elevonSlider2->setValue(field->getDouble(ti)*100);
+ // Find the channel number for Elevon1 (FixedWingRoll1)
+ channel = m_aircraft->fwAileron1ChannelBox->currentIndex()-1;
+ if (channel > -1) { // If for some reason the actuators were incoherent, we might fail here, hence the check.
+ m_aircraft->elevonSlider1->setValue(getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_ROLL)*100);
+ m_aircraft->elevonSlider2->setValue(getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_PITCH)*100);
}
}
- if (frameType == "FixedWingVtail") {
- obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings")));
- Q_ASSERT(obj);
- int chMixerNumber = m_aircraft->fwElevator1ChannelBox->currentIndex()-1;
- if (chMixerNumber >=0) {
- field = obj->getField(mixerVectors.at(chMixerNumber));
- int ti = field->getElementNames().indexOf("Yaw");
- m_aircraft->elevonSlider1->setValue(field->getDouble(ti)*100);
- ti = field->getElementNames().indexOf("Pitch");
- m_aircraft->elevonSlider2->setValue(field->getDouble(ti)*100);
- }
- }
-
+ if (frameType == "FixedWingVtail") {
+ channel = m_aircraft->fwElevator1ChannelBox->currentIndex()-1;
+ if (channel > -1) { // If for some reason the actuators were incoherent, we might fail here, hence the check.
+ m_aircraft->elevonSlider1->setValue(getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_YAW)*100);
+ m_aircraft->elevonSlider2->setValue(getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_PITCH)*100);
+ }
+ }
}
@@ -312,7 +300,10 @@ bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType)
int channel;
//disable all
for (channel=0; channelfwEngineChannelBox->currentIndex()-1;
@@ -396,7 +387,10 @@ bool ConfigFixedWingWidget::setupFrameElevon(QString airframeType)
double value;
//disable all
for (channel=0; channelfwEngineChannelBox->currentIndex()-1;
@@ -478,7 +472,10 @@ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType)
double value;
//disable all
for (channel=0; channelfwEngineChannelBox->currentIndex()-1;
diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.cpp b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.cpp
index 35044965d..5b390c0e3 100644
--- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.cpp
+++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.cpp
@@ -25,7 +25,6 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "configmultirotorwidget.h"
-#include "mixersettings.h"
#include
#include
@@ -296,12 +295,8 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
field = obj->getField(QString("MaxAccel"));
field->setDouble(m_aircraft->maxAccelSlider->value());
- // Curve is also common to all quads:
- field = obj->getField("ThrottleCurve1");
- QList curve = m_aircraft->multiThrottleCurve->getCurve();
- for (int i=0;isetValue(curve.at(i),i);
- }
+ // Curve is also common to all quads:
+ setThrottleCurve(obj, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->multiThrottleCurve->getCurve() );
if (m_aircraft->multirotorFrameType->currentText() == "Quad +") {
airframeType = "QuadP";
@@ -1036,20 +1031,22 @@ bool ConfigMultiRotorWidget::setupMultiRotorMixer(double mixerFactors[8][3])
qDebug()< mmList;
mmList << m_aircraft->multiMotorChannelBox1 << m_aircraft->multiMotorChannelBox2 << m_aircraft->multiMotorChannelBox3
<< m_aircraft->multiMotorChannelBox4 << m_aircraft->multiMotorChannelBox5 << m_aircraft->multiMotorChannelBox6
<< m_aircraft->multiMotorChannelBox7 << m_aircraft->multiMotorChannelBox8;
- UAVDataObject *obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings")));
- // 1. Assign the servo/motor/none for each channel
- // Disable all
- foreach(QString mixer, mixerTypes) {
- field = obj->getField(mixer);
- Q_ASSERT(field);
- field->setValue("Disabled");
+
+ UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings")));
+ Q_ASSERT(mixer);
+
+ //disable all
+ for (int channel=0; channelmrPitchMixLevel->value()/100;
double rFactor = (double)m_aircraft->mrRollMixLevel->value()/100;
diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.h b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.h
index 7a275e401..3ccc0de6b 100644
--- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.h
+++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.h
@@ -29,6 +29,7 @@
#include "ui_airframe.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
+#include "cfg_vehicletypes/vehicleconfig.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.cpp b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.cpp
index a5b1ac8b4..549778540 100644
--- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.cpp
+++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.cpp
@@ -233,6 +233,60 @@ void VehicleConfig::setMixerVectorValue(UAVDataObject* mixer, int channel, Mixer
}
}
+void VehicleConfig::setThrottleCurve(UAVDataObject* mixer, MixerThrottleCurveElem curveType, QList curve)
+{
+ QPointer field;
+
+ switch (curveType)
+ {
+ case MIXER_THROTTLECURVE1:
+ {
+ field = mixer->getField("ThrottleCurve1");
+ break;
+ }
+ case MIXER_THROTTLECURVE2:
+ {
+ field = mixer->getField("ThrottleCurve2");
+ break;
+ }
+ }
+
+ if (field && field->getNumElements() == curve.length()) {
+ for (int i=0;isetValue(curve.at(i),i);
+ }
+ }
+}
+
+void VehicleConfig::getThrottleCurve(UAVDataObject* mixer, MixerThrottleCurveElem curveType, QList* curve)
+{
+ Q_ASSERT(mixer);
+ Q_ASSERT(curve);
+
+ QPointer field;
+
+ switch (curveType)
+ {
+ case MIXER_THROTTLECURVE1:
+ {
+ field = mixer->getField("ThrottleCurve1");
+ break;
+ }
+ case MIXER_THROTTLECURVE2:
+ {
+ field = mixer->getField("ThrottleCurve2");
+ break;
+ }
+ }
+
+ if (field) {
+ curve->clear();
+ for (unsigned int i=0; i < field->getNumElements(); i++) {
+ curve->append(field->getValue(i).toDouble());
+ }
+ }
+}
+
/**
Reset the contents of a field
*/
diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.h b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.h
index 9700a8789..343cfcf0c 100644
--- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.h
+++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.h
@@ -111,6 +111,9 @@ class VehicleConfig: public ConfigTaskWidget
VehicleConfig(QWidget *parent = 0);
~VehicleConfig();
+ /* Enumeration options for ThrottleCurves */
+ typedef enum { MIXER_THROTTLECURVE1=0, MIXER_THROTTLECURVE2=1 } MixerThrottleCurveElem;
+
/* Enumeration options for field MixerType */
typedef enum { MIXERTYPE_DISABLED=0, MIXERTYPE_MOTOR=1, MIXERTYPE_SERVO=2, MIXERTYPE_CAMERAROLL=3, MIXERTYPE_CAMERAPITCH=4, MIXERTYPE_CAMERAYAW=5, MIXERTYPE_ACCESSORY0=6, MIXERTYPE_ACCESSORY1=7, MIXERTYPE_ACCESSORY2=8, MIXERTYPE_ACCESSORY3=9, MIXERTYPE_ACCESSORY4=10, MIXERTYPE_ACCESSORY5=11 } MixerTypeElem;
/* Array element names for field MixerVector */
@@ -127,6 +130,8 @@ class VehicleConfig: public ConfigTaskWidget
void resetMixerVector(UAVDataObject* mixer, int channel);
QString getMixerType(UAVDataObject* mixer, int channel);
void setMixerType(UAVDataObject* mixer, int channel, MixerTypeElem mixerType);
+ void setThrottleCurve(UAVDataObject* mixer, MixerThrottleCurveElem curveType, QList curve);
+ void getThrottleCurve(UAVDataObject* mixer, MixerThrottleCurveElem curveType, QList* curve);
virtual void ResetActuators(GUIConfigDataUnion* configData);
virtual QStringList getChannelDescriptions();
diff --git a/ground/openpilotgcs/src/plugins/config/configinputwidget.cpp b/ground/openpilotgcs/src/plugins/config/configinputwidget.cpp
index 4a2130b26..ba1dbb74e 100644
--- a/ground/openpilotgcs/src/plugins/config/configinputwidget.cpp
+++ b/ground/openpilotgcs/src/plugins/config/configinputwidget.cpp
@@ -46,7 +46,7 @@
#define STICK_MIN_MOVE -8
#define STICK_MAX_MOVE 8
-ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent),wizardStep(wizardNone),loop(NULL),skipflag(false),transmitterType(heli)
+ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent),wizardStep(wizardNone),transmitterType(heli),loop(NULL),skipflag(false)
{
manualCommandObj = ManualControlCommand::GetInstance(getObjectManager());
manualSettingsObj = ManualControlSettings::GetInstance(getObjectManager());
diff --git a/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.cpp b/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.cpp
index 45e4285e9..19047af55 100644
--- a/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.cpp
+++ b/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.cpp
@@ -36,10 +36,11 @@
#include
#include
#include
+#include
+
#include "systemsettings.h"
#include "mixersettings.h"
#include "actuatorsettings.h"
-#include
/**
Helper delegate for the custom mixer editor table.
@@ -119,7 +120,8 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi
airframeTypes << "Fixed Wing" << "Multirotor" << "Helicopter" << "Ground" << "Custom";
m_aircraft->aircraftType->addItems(airframeTypes);
- m_aircraft->aircraftType->setCurrentIndex(0); //Set default vehicle to Fixed Wing
+ m_aircraft->aircraftType->setCurrentIndex(0); //Set default vehicle to Fixed Wing
+ m_aircraft->airframesWidget->setCurrentIndex(0); // Force the tab index to match
QStringList fixedWingTypes;
fixedWingTypes << "Elevator aileron rudder" << "Elevon" << "Vtail";
@@ -780,77 +782,65 @@ void ConfigVehicleTypeWidget::resetField(UAVObjectField * field)
Note: does NOT ask for an object refresh itself!
*/
void ConfigVehicleTypeWidget::updateCustomAirframeUI()
-{
+{
+ UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings")));
+ Q_ASSERT(mixer);
+
+ VehicleConfig* vconfig = new VehicleConfig();
+
QList curveValues;
- UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings")));
- Q_ASSERT(obj);
+ // setup throttlecurve 1
+ vconfig->getThrottleCurve(mixer,VehicleConfig::MIXER_THROTTLECURVE1,&curveValues);
- UAVObjectField* field = obj->getField(QString("ThrottleCurve1"));
- if (field)
- {
- // If the 1st element of the curve is <= -10, then the curve
- // is a straight line (that's how the mixer works on the mainboard):
- if (field->getValue(0).toInt() <= -10) {
- m_aircraft->customThrottle1Curve->initLinearCurve(field->getNumElements(),(double)1);
- } else {
- double temp=0;
- double value;
- for (unsigned int i=0; i < field->getNumElements(); i++) {
- value=field->getValue(i).toDouble();
- temp+=value;
- curveValues.append(value);
- }
- if(temp==0)
- m_aircraft->customThrottle1Curve->initLinearCurve(field->getNumElements(),(double)1);
- else
- m_aircraft->customThrottle1Curve->initCurve(curveValues);
- }
+ int total = 0;
+ for (int i=0; icustomThrottle1Curve->initLinearCurve(curveValues.length(),(double)1);
+ }
+ else {
+ m_aircraft->customThrottle1Curve->initCurve(curveValues);
}
- curveValues.clear();
+ // setup throttlecurve 2
+ vconfig->getThrottleCurve(mixer,VehicleConfig::MIXER_THROTTLECURVE2,&curveValues);
- field = obj->getField(QString("ThrottleCurve2"));
- if (field)
- {
- // If the 1st element of the curve is <= -10, then the curve
- // is a straight line (that's how the mixer works on the mainboard):
- if (field->getValue(0).toInt() <= -10) {
- m_aircraft->customThrottle2Curve->initLinearCurve(field->getNumElements(),(double)1);
- } else {
- for (unsigned int i=0; i < field->getNumElements(); i++) {
- curveValues.append(field->getValue(i).toDouble());
- }
- m_aircraft->customThrottle2Curve->initCurve(curveValues);
- }
+ total = 0;
+ for (int i=0; icustomThrottle2Curve->initLinearCurve(curveValues.length(),(double)1);
+ }
+ else {
+ m_aircraft->customThrottle2Curve->initCurve(curveValues);
}
- // Update the table:
- for (int i=0; i<8; i++) {
- field = obj->getField(mixerTypes.at(i));
+
+ // Update the mixer table:
+ for (int channel=0; channel<8; channel++) {
+ UAVObjectField* field = mixer->getField(mixerTypes.at(channel));
if (field)
{
- QComboBox* q = (QComboBox*)m_aircraft->customMixerTable->cellWidget(0,i);
+ QComboBox* q = (QComboBox*)m_aircraft->customMixerTable->cellWidget(0,channel);
if (q)
{
QString s = field->getValue().toString();
setComboCurrentIndex(q, q->findText(s));
}
- field = obj->getField(mixerVectors.at(i));
- if (field)
- {
- int ti = field->getElementNames().indexOf("ThrottleCurve1");
- m_aircraft->customMixerTable->item(1,i)->setText(field->getValue(ti).toString());
- ti = field->getElementNames().indexOf("ThrottleCurve2");
- m_aircraft->customMixerTable->item(2,i)->setText(field->getValue(ti).toString());
- ti = field->getElementNames().indexOf("Roll");
- m_aircraft->customMixerTable->item(3,i)->setText(field->getValue(ti).toString());
- ti = field->getElementNames().indexOf("Pitch");
- m_aircraft->customMixerTable->item(4,i)->setText(field->getValue(ti).toString());
- ti = field->getElementNames().indexOf("Yaw");
- m_aircraft->customMixerTable->item(5,i)->setText(field->getValue(ti).toString());
- }
+ m_aircraft->customMixerTable->item(1,channel)->setText(
+ QString::number(vconfig->getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1)));
+ m_aircraft->customMixerTable->item(2,channel)->setText(
+ QString::number(vconfig->getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE2)));
+ m_aircraft->customMixerTable->item(3,channel)->setText(
+ QString::number(vconfig->getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_ROLL)));
+ m_aircraft->customMixerTable->item(4,channel)->setText(
+ QString::number(vconfig->getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_PITCH)));
+ m_aircraft->customMixerTable->item(5,channel)->setText(
+ QString::number(vconfig->getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_YAW)));
}
}
}
@@ -865,9 +855,6 @@ void ConfigVehicleTypeWidget::updateCustomAirframeUI()
*/
void ConfigVehicleTypeWidget::updateObjectsFromWidgets()
{
- UAVDataObject* obj;
- UAVObjectField* field;
-
QString airframeType = "Custom"; //Sets airframe type default to "Custom"
if (m_aircraft->aircraftType->currentText() == "Fixed Wing") {
airframeType = m_fixedwing->updateConfigObjectsFromWidgets();
@@ -882,45 +869,42 @@ void ConfigVehicleTypeWidget::updateObjectsFromWidgets()
airframeType = m_groundvehicle->updateConfigObjectsFromWidgets();
}
else {
- obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings")));
- field = obj->getField(QString("FeedForward"));
- // Curve is also common to all quads:
- field = obj->getField("ThrottleCurve1");
- QList curve = m_aircraft->customThrottle1Curve->getCurve();
- for (int i=0;isetValue(curve.at(i),i);
- }
+ UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings")));
+ Q_ASSERT(mixer);
- field = obj->getField("ThrottleCurve2");
- curve.clear();
- curve = m_aircraft->customThrottle2Curve->getCurve();
- for (int i=0;isetValue(curve.at(i),i);
- }
+ VehicleConfig* vconfig = new VehicleConfig();
+
+ vconfig->setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->customThrottle1Curve->getCurve());
+ vconfig->setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, m_aircraft->customThrottle2Curve->getCurve());
// Update the table:
- for (int i=0; i<8; i++) {
- field = obj->getField(mixerTypes.at(i));
- QComboBox* q = (QComboBox*)m_aircraft->customMixerTable->cellWidget(0,i);
- field->setValue(q->currentText());
- field = obj->getField(mixerVectors.at(i));
- int ti = field->getElementNames().indexOf("ThrottleCurve1");
- field->setValue(m_aircraft->customMixerTable->item(1,i)->text(),ti);
- ti = field->getElementNames().indexOf("ThrottleCurve2");
- field->setValue(m_aircraft->customMixerTable->item(2,i)->text(),ti);
- ti = field->getElementNames().indexOf("Roll");
- field->setValue(m_aircraft->customMixerTable->item(3,i)->text(),ti);
- ti = field->getElementNames().indexOf("Pitch");
- field->setValue(m_aircraft->customMixerTable->item(4,i)->text(),ti);
- ti = field->getElementNames().indexOf("Yaw");
- field->setValue(m_aircraft->customMixerTable->item(5,i)->text(),ti);
+ for (int channel=0; channel<8; channel++) {
+ QComboBox* q = (QComboBox*)m_aircraft->customMixerTable->cellWidget(0,channel);
+
+ vconfig->setMixerType(mixer,channel,
+ q->currentText() == "Servo" ? VehicleConfig::MIXERTYPE_SERVO : VehicleConfig::MIXERTYPE_MOTOR);
+
+ vconfig->setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1,
+ m_aircraft->customMixerTable->item(1,channel)->text().toDouble());
+ vconfig->setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE2,
+ m_aircraft->customMixerTable->item(2,channel)->text().toDouble());
+ vconfig->setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_ROLL,
+ m_aircraft->customMixerTable->item(3,channel)->text().toDouble());
+ vconfig->setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_PITCH,
+ m_aircraft->customMixerTable->item(4,channel)->text().toDouble());
+ vconfig->setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_YAW,
+ m_aircraft->customMixerTable->item(5,channel)->text().toDouble());
}
}
+
// set the airframe type
- obj = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings")));
- field = obj->getField(QString("AirframeType"));
- field->setValue(airframeType);
+ UAVDataObject* system = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings")));
+ Q_ASSERT(system);
+
+ QPointer field = system->getField(QString("AirframeType"));
+ if (field)
+ field->setValue(airframeType);
updateCustomAirframeUI();
}
diff --git a/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.h b/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.h
index d128acaf5..3cca72ba1 100644
--- a/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.h
+++ b/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.h
@@ -38,6 +38,7 @@
#include "cfg_vehicletypes/configfixedwingwidget.h"
#include "cfg_vehicletypes/configmultirotorwidget.h"
#include "cfg_vehicletypes/configgroundvehiclewidget.h"
+#include "cfg_vehicletypes/vehicleconfig.h"
#include
#include
diff --git a/ground/openpilotgcs/src/plugins/config/stabilization.ui b/ground/openpilotgcs/src/plugins/config/stabilization.ui
index fd6b01ca8..3f985a66e 100755
--- a/ground/openpilotgcs/src/plugins/config/stabilization.ui
+++ b/ground/openpilotgcs/src/plugins/config/stabilization.ui
@@ -495,7 +495,7 @@
0
- -114
+ 0
673
790
@@ -11797,7 +11797,7 @@ border-radius: 4;
- -
+
-
@@ -11850,7 +11850,7 @@ border-radius: 4;
- -
+
-
@@ -14693,6 +14693,19 @@ value as the Kp.
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
@@ -15272,7 +15285,7 @@ value as the Kp.
false
- -
+
-
@@ -17936,7 +17949,7 @@ border-radius: 5;
- -
+
-
@@ -17999,6 +18012,19 @@ border-radius: 4;
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
diff --git a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2.pro b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2.pro
index f567fc401..58475b05f 100644
--- a/ground/openpilotgcs/src/plugins/hitlv2/hitlv2.pro
+++ b/ground/openpilotgcs/src/plugins/hitlv2/hitlv2.pro
@@ -1,5 +1,5 @@
TEMPLATE = lib
-TARGET = HITLV2
+TARGET = HITLv2
QT += network
include(../../openpilotgcsplugin.pri)
include(hitlv2_dependencies.pri)
diff --git a/ground/openpilotgcs/src/plugins/serialconnection/serialplugin.cpp b/ground/openpilotgcs/src/plugins/serialconnection/serialplugin.cpp
index f83efe968..1f7a476f0 100644
--- a/ground/openpilotgcs/src/plugins/serialconnection/serialplugin.cpp
+++ b/ground/openpilotgcs/src/plugins/serialconnection/serialplugin.cpp
@@ -128,7 +128,7 @@ QList SerialConnection::availableDevices()
foreach( QextPortInfo port, ports ) {
device d;
d.displayName=port.friendName;
- d.name=port.friendName;
+ d.name=port.physName;
list.append(d);
}
}
@@ -143,7 +143,7 @@ QIODevice *SerialConnection::openDevice(const QString &deviceName)
}
QList ports = QextSerialEnumerator::getPorts();
foreach( QextPortInfo port, ports ) {
- if(port.friendName == deviceName)
+ if(port.physName == deviceName)
{
//we need to handle port settings here...
PortSettings set;
diff --git a/ground/openpilotgcs/src/plugins/uavobjectbrowser/treeitem.cpp b/ground/openpilotgcs/src/plugins/uavobjectbrowser/treeitem.cpp
index ced1bfcba..a6924e71d 100644
--- a/ground/openpilotgcs/src/plugins/uavobjectbrowser/treeitem.cpp
+++ b/ground/openpilotgcs/src/plugins/uavobjectbrowser/treeitem.cpp
@@ -27,6 +27,77 @@
#include "treeitem.h"
+/* Constructor */
+HighLightManager::HighLightManager(long checkingInterval)
+{
+ // Start the timer and connect it to the callback
+ m_expirationTimer.start(checkingInterval);
+ connect(&m_expirationTimer, SIGNAL(timeout()), this, SLOT(checkItemsExpired()));
+}
+
+/*
+ * Called to add item to list. Item is only added if absent.
+ * Returns true if item was added, otherwise false.
+ */
+bool HighLightManager::add(TreeItem *itemToAdd)
+{
+ // Lock to ensure thread safety
+ QMutexLocker locker(&m_listMutex);
+
+ // Check so that the item isn't already in the list
+ if(!m_itemsList.contains(itemToAdd))
+ {
+ m_itemsList.append(itemToAdd);
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Called to remove item from list.
+ * Returns true if item was removed, otherwise false.
+ */
+bool HighLightManager::remove(TreeItem *itemToRemove)
+{
+ // Lock to ensure thread safety
+ QMutexLocker locker(&m_listMutex);
+
+ // Remove item and return result
+ return m_itemsList.removeOne(itemToRemove);
+}
+
+/*
+ * Callback called periodically by the timer.
+ * This method checks for expired highlights and
+ * removes them if they are expired.
+ * Expired highlights are restored.
+ */
+void HighLightManager::checkItemsExpired()
+{
+ // Lock to ensure thread safety
+ QMutexLocker locker(&m_listMutex);
+
+ // Get a mutable iterator for the list
+ QMutableLinkedListIterator iter(m_itemsList);
+
+ // This is the timestamp to compare with
+ QTime now = QTime::currentTime();
+
+ // Loop over all items, check if they expired.
+ while(iter.hasNext())
+ {
+ TreeItem* item = iter.next();
+ if(item->getHiglightExpires() < now)
+ {
+ // If expired, call removeHighlight
+ item->removeHighlight();
+
+ // Remove from list since it is restored.
+ iter.remove();
+ }
+ }
+}
+
int TreeItem::m_highlightTimeMs = 500;
TreeItem::TreeItem(const QList &data, TreeItem *parent) :
@@ -36,7 +107,6 @@ TreeItem::TreeItem(const QList &data, TreeItem *parent) :
m_highlight(false),
m_changed(false)
{
- connect(&m_timer, SIGNAL(timeout()), this, SLOT(removeHighlight()));
}
TreeItem::TreeItem(const QVariant &data, TreeItem *parent) :
@@ -46,7 +116,6 @@ TreeItem::TreeItem(const QVariant &data, TreeItem *parent) :
m_changed(false)
{
m_data << data << "" << "";
- connect(&m_timer, SIGNAL(timeout()), this, SLOT(removeHighlight()));
}
TreeItem::~TreeItem()
@@ -108,21 +177,50 @@ void TreeItem::apply() {
child->apply();
}
+/*
+ * Called after a value has changed to trigger highlightning of tree item.
+ */
void TreeItem::setHighlight(bool highlight) {
m_highlight = highlight;
m_changed = false;
if (highlight) {
- if (m_timer.isActive()) {
- m_timer.stop();
+ // Update the expires timestamp
+ m_highlightExpires = QTime::currentTime().addMSecs(m_highlightTimeMs);
+
+ // Add to highlightmanager
+ if(m_highlightManager->add(this))
+ {
+ // Only emit signal if it was added
+ emit updateHighlight(this);
}
- m_timer.setSingleShot(true);
- m_timer.start(m_highlightTimeMs);
}
- emit updateHighlight(this);
+ else if(m_highlightManager->remove(this))
+ {
+ // Only emit signal if it was removed
+ emit updateHighlight(this);
+ }
+
+ // If we have a parent, call recursively to update highlight status of parents.
+ // This will ensure that the root of a leaf that is changed also is highlighted.
+ // Only updates that really changes values will trigger highlight of parents.
+ if(m_parent)
+ {
+ m_parent->setHighlight(highlight);
+ }
}
void TreeItem::removeHighlight() {
m_highlight = false;
- update();
+ //update();
emit updateHighlight(this);
}
+
+void TreeItem::setHighlightManager(HighLightManager *mgr)
+{
+ m_highlightManager = mgr;
+}
+
+QTime TreeItem::getHiglightExpires()
+{
+ return m_highlightExpires;
+}
diff --git a/ground/openpilotgcs/src/plugins/uavobjectbrowser/treeitem.h b/ground/openpilotgcs/src/plugins/uavobjectbrowser/treeitem.h
index 937631b05..c4f8e0355 100644
--- a/ground/openpilotgcs/src/plugins/uavobjectbrowser/treeitem.h
+++ b/ground/openpilotgcs/src/plugins/uavobjectbrowser/treeitem.h
@@ -32,10 +32,58 @@
#include "uavmetaobject.h"
#include "uavobjectfield.h"
#include
+#include
#include
+#include
#include
#include
+#include
+class TreeItem;
+
+/*
+* Small utility class that handles the higlighting of
+* tree grid items.
+* Basicly it maintains all items due to be restored to
+* non highlighted state in a linked list.
+* A timer traverses this list periodically to find out
+* if any of the items should be restored. All items are
+* updated withan expiration timestamp when they expires.
+* An item that is beeing restored is removed from the
+* list and its removeHighlight() method is called. Items
+* that are not expired are left in the list til next time.
+* Items that are updated during the expiration time are
+* left untouched in the list. This reduces unwanted emits
+* of signals to the repaint/update function.
+*/
+class HighLightManager : public QObject
+{
+Q_OBJECT
+public:
+ // Constructor taking the checking interval in ms.
+ HighLightManager(long checkingInterval);
+
+ // This is called when an item has been set to
+ // highlighted = true.
+ bool add(TreeItem* itemToAdd);
+
+ //This is called when an item is set to highlighted = false;
+ bool remove(TreeItem* itemToRemove);
+
+private slots:
+ // Timer callback method.
+ void checkItemsExpired();
+
+private:
+ // The timer checking highlight expiration.
+ QTimer m_expirationTimer;
+
+ // The list holding all items due to be updated.
+ QLinkedList m_itemsList;
+
+ //Mutex to lock when accessing list.
+ QMutex m_listMutex;
+};
class TreeItem : public QObject
{
@@ -77,11 +125,16 @@ public:
inline bool changed() { return m_changed; }
inline void setChanged(bool changed) { m_changed = changed; }
+ virtual void setHighlightManager(HighLightManager* mgr);
+
+ QTime getHiglightExpires();
+
+ virtual void removeHighlight();
+
signals:
void updateHighlight(TreeItem*);
private slots:
- void removeHighlight();
private:
QList m_children;
@@ -91,7 +144,8 @@ private:
TreeItem *m_parent;
bool m_highlight;
bool m_changed;
- QTimer m_timer;
+ QTime m_highlightExpires;
+ HighLightManager* m_highlightManager;
public:
static const int dataColumn = 1;
private:
diff --git a/ground/openpilotgcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp b/ground/openpilotgcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp
index ac2e4bcee..9bd8b20b4 100644
--- a/ground/openpilotgcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp
+++ b/ground/openpilotgcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp
@@ -47,6 +47,8 @@ UAVObjectTreeModel::UAVObjectTreeModel(QObject *parent) :
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject();
+ // Create highlight manager, let it run every 300 ms.
+ m_highlightManager = new HighLightManager(300);
connect(objManager, SIGNAL(newObject(UAVObject*)), this, SLOT(newObject(UAVObject*)));
connect(objManager, SIGNAL(newInstance(UAVObject*)), this, SLOT(newObject(UAVObject*)));
@@ -56,6 +58,7 @@ UAVObjectTreeModel::UAVObjectTreeModel(QObject *parent) :
UAVObjectTreeModel::~UAVObjectTreeModel()
{
+ delete m_highlightManager;
delete m_rootItem;
}
@@ -67,9 +70,12 @@ void UAVObjectTreeModel::setupModelData(UAVObjectManager *objManager)
m_rootItem = new TreeItem(rootData);
m_settingsTree = new TopTreeItem(tr("Settings"), m_rootItem);
+ m_settingsTree->setHighlightManager(m_highlightManager);
m_rootItem->appendChild(m_settingsTree);
m_nonSettingsTree = new TopTreeItem(tr("Data Objects"), m_rootItem);
+ m_nonSettingsTree->setHighlightManager(m_highlightManager);
m_rootItem->appendChild(m_nonSettingsTree);
+ m_rootItem->setHighlightManager(m_highlightManager);
connect(m_settingsTree, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
connect(m_nonSettingsTree, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
@@ -96,6 +102,7 @@ void UAVObjectTreeModel::addDataObject(UAVDataObject *obj)
addInstance(obj, root->child(index));
} else {
DataObjectTreeItem *data = new DataObjectTreeItem(obj->getName() + " (" + QString::number(obj->getNumBytes()) + " bytes)");
+ data->setHighlightManager(m_highlightManager);
connect(data, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
int index = root->nameIndex(obj->getName());
root->insert(index, data);
@@ -110,6 +117,7 @@ void UAVObjectTreeModel::addMetaObject(UAVMetaObject *obj, TreeItem *parent)
{
connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(highlightUpdatedObject(UAVObject*)));
MetaObjectTreeItem *meta = new MetaObjectTreeItem(obj, tr("Meta Data"));
+ meta->setHighlightManager(m_highlightManager);
connect(meta, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
foreach (UAVObjectField *field, obj->getFields()) {
if (field->getNumElements() > 1) {
@@ -132,6 +140,7 @@ void UAVObjectTreeModel::addInstance(UAVObject *obj, TreeItem *parent)
} else {
QString name = tr("Instance") + " " + QString::number(obj->getInstID());
item = new InstanceTreeItem(obj, name);
+ item->setHighlightManager(m_highlightManager);
connect(item, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
parent->appendChild(item);
}
@@ -148,6 +157,7 @@ void UAVObjectTreeModel::addInstance(UAVObject *obj, TreeItem *parent)
void UAVObjectTreeModel::addArrayField(UAVObjectField *field, TreeItem *parent)
{
TreeItem *item = new ArrayFieldTreeItem(field->getName());
+ item->setHighlightManager(m_highlightManager);
connect(item, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
for (uint i = 0; i < field->getNumElements(); ++i) {
addSingleField(i, field, item);
@@ -192,6 +202,7 @@ void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeIt
default:
Q_ASSERT(false);
}
+ item->setHighlightManager(m_highlightManager);
connect(item, SIGNAL(updateHighlight(TreeItem*)), this, SLOT(updateHighlight(TreeItem*)));
parent->appendChild(item);
}
@@ -352,7 +363,6 @@ void UAVObjectTreeModel::highlightUpdatedObject(UAVObject *obj)
Q_ASSERT(obj);
ObjectTreeItem *item = findObjectTreeItem(obj);
Q_ASSERT(item);
- item->setHighlight(true);
item->update();
QModelIndex itemIndex = index(item);
Q_ASSERT(itemIndex != QModelIndex());
diff --git a/ground/openpilotgcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.h b/ground/openpilotgcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.h
index 17399611c..d9787e3a7 100644
--- a/ground/openpilotgcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.h
+++ b/ground/openpilotgcs/src/plugins/uavobjectbrowser/uavobjecttreemodel.h
@@ -97,6 +97,9 @@ private:
int m_recentlyUpdatedTimeout;
QColor m_recentlyUpdatedColor;
QColor m_manuallyChangedColor;
+
+ // Highlight manager to handle highlighting of tree items.
+ HighLightManager *m_highlightManager;
};
#endif // UAVOBJECTTREEMODEL_H
diff --git a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/configtaskwidget.h b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/configtaskwidget.h
index 76d6b55bd..3cac0abc0 100644
--- a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/configtaskwidget.h
+++ b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/configtaskwidget.h
@@ -84,7 +84,7 @@ public:
};
ConfigTaskWidget(QWidget *parent = 0);
- ~ConfigTaskWidget();
+ virtual ~ConfigTaskWidget();
void disableMouseWheelEvents();
bool eventFilter( QObject * obj, QEvent * evt );
diff --git a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvepoint.cpp b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvepoint.cpp
index 6eaa8f5ed..64b9912b1 100644
--- a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvepoint.cpp
+++ b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvepoint.cpp
@@ -43,6 +43,7 @@ Node::Node(MixerCurveWidget *graphWidget)
setCacheMode(DeviceCoordinateCache);
setZValue(-1);
vertical = false;
+ value = 0;
}
void Node::addEdge(Edge *edge)
@@ -98,6 +99,15 @@ void Node::verticalMove(bool flag){
vertical = flag;
}
+double Node::getValue() {
+ return value;
+}
+
+void Node::setValue(double val) {
+ value = val;
+}
+
+
QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
{
@@ -117,11 +127,19 @@ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
newPos.setY(h);
return newPos;
}
- case ItemPositionHasChanged:
+ case ItemPositionHasChanged: {
foreach (Edge *edge, edgeList)
edge->adjust();
- graph->itemMoved((h-newPos.y())/h);
+
+ double min = graph->getMin();
+ double range = graph->getMax() - min;
+ double ratio = (h - newPos.y()) / h;
+ double val = (range * ratio ) + min;
+ setValue(val);
+
+ graph->itemMoved(val);
break;
+ }
default:
break;
};
diff --git a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvepoint.h b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvepoint.h
index 987875e32..19b940625 100644
--- a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvepoint.h
+++ b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvepoint.h
@@ -48,12 +48,16 @@ public:
enum { Type = UserType + 1 };
int type() const { return Type; }
+
void verticalMove(bool flag);
QRectF boundingRect() const;
QPainterPath shape() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ void setValue(double val);
+ double getValue();
+
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
@@ -61,6 +65,8 @@ protected:
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
private:
+
+ double value;
QList edgeList;
QPointF newPos;
MixerCurveWidget *graph;
diff --git a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvewidget.cpp b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvewidget.cpp
index f21d782f6..56ed8bee9 100644
--- a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvewidget.cpp
+++ b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvewidget.cpp
@@ -32,8 +32,6 @@
#include
#include
-
-
/*
* Initialize the widget
*/
@@ -74,11 +72,48 @@ MixerCurveWidget::MixerCurveWidget(QWidget *parent) : QGraphicsView(parent)
scene->setSceneRect(plot->boundingRect());
setScene(scene);
+ initNodes(MixerCurveWidget::NODE_NUMELEM);
}
MixerCurveWidget::~MixerCurveWidget()
{
+ for (int i=0; i= 0 && index < nodePool.count())
+ {
+ node = nodePool.at(index);
+ }
+ else {
+ node = new Node(this);
+ nodePool.append(node);
+ }
+ return node;
+}
+
+Edge* MixerCurveWidget::getEdge(int index, Node* sourceNode, Node* destNode)
+{
+ Edge* edge;
+
+ if (index >= 0 && index < edgePool.count())
+ {
+ edge = edgePool.at(index);
+ edge->setSourceNode(sourceNode);
+ edge->setDestNode(destNode);
+ }
+ else {
+ edge = new Edge(sourceNode,destNode);
+ edgePool.append(edge);
+ }
+ return edge;
}
/**
@@ -89,60 +124,62 @@ MixerCurveWidget::~MixerCurveWidget()
*/
void MixerCurveWidget::initCurve(QList points)
{
-
if (points.length() < 2)
return; // We need at least 2 points on a curve!
- // First of all, reset the list
- // TODO: one edge might not get deleted properly, small mem leak maybe...
+ if (nodeList.count() != points.count())
+ initNodes(points.count());
+
+ // finally, set node positions
+ setCurve(points);
+}
+
+void MixerCurveWidget::initNodes(int numPoints)
+{
+ // First of all, clear any existing list
+ if (nodeList.count()) {
foreach (Node *node, nodeList ) {
QList edges = node->edges();
foreach(Edge *edge, edges) {
- if (scene()->items().contains(edge))
- scene()->removeItem(edge);
- else
+ if (edge->destNode() == node) {
delete edge;
+ }
+ else {
+ scene()->removeItem(edge);
+ }
}
- scene()->removeItem(node);
- delete node;
- }
- nodeList.clear();
+ scene()->removeItem(node);
+ }
+
+ nodeList.clear();
+ }
+
+ // Create the nodes and edges
+ Node* prevNode = 0;
+ for (int i=0; iboundingRect().width()/(points.length()-1);
- qreal h = plot->boundingRect().height();
- for (int i=0; iaddItem(node);
nodeList.append(node);
- double val = points.at(i);
- if (val>curveMax)
- val=curveMax;
- if (valsetPos(w*i,h-val*h);
- node->verticalMove(true);
- }
+ scene()->addItem(node);
- // ... and link them together:
- for (int i=0; i<(points.length()-1); i++) {
- scene()->addItem(new Edge(nodeList.at(i),nodeList.at(i+1)));
- }
+ if (prevNode) {
+ scene()->addItem(getEdge(i, prevNode, node));
+ }
+ prevNode = node;
+ }
}
-
/**
Returns the current curve settings
*/
QList MixerCurveWidget::getCurve() {
+
QList list;
- qreal h = plot->boundingRect().height();
foreach(Node *node, nodeList) {
- list.append(((curveMax-curveMin)*(h-node->pos().y())/h)+curveMin);
+ list.append(node->getValue());
}
return list;
@@ -150,11 +187,15 @@ QList MixerCurveWidget::getCurve() {
/**
Sets a linear graph
*/
-void MixerCurveWidget::initLinearCurve(quint32 numPoints, double maxValue)
+void MixerCurveWidget::initLinearCurve(quint32 numPoints, double maxValue, double minValue)
{
+ Q_UNUSED(maxValue);
+ Q_UNUSED(minValue);
+
QList points;
for (double i=0; i points)
{
- if (nodeList.length()<1)
- {
- initCurve(points);
- }
- else
- {
- qreal w = plot->boundingRect().width()/(points.length()-1);
- qreal h = plot->boundingRect().height();
- for (int i=0; icurveMax)
- val=curveMax;
- if (valsetPos(w*i,h-val*h);
- }
+ curveUpdating = true;
+
+ if (nodeList.count() != points.count())
+ initNodes(points.count());
+
+ double min = curveMin + 10;
+ double max = curveMax + 10;
+
+ qreal w = plot->boundingRect().width()/(points.count()-1);
+ qreal h = plot->boundingRect().height();
+ for (int i=0; i curveMax)
+ val = curveMax;
+
+ val += 10;
+ val -= min;
+ val /= (max - min);
+
+ nodeList.at(i)->setPos(w*i, h - (val*h));
+ nodeList.at(i)->verticalMove(true);
}
+
+ curveUpdating = false;
+
+ emit curveUpdated(points, (double)0);
}
@@ -205,8 +256,10 @@ void MixerCurveWidget::resizeEvent(QResizeEvent* event)
void MixerCurveWidget::itemMoved(double itemValue)
{
- QList list = getCurve();
- emit curveUpdated(list, itemValue);
+ if (!curveUpdating) {
+ QList list = getCurve();
+ emit curveUpdated(list, itemValue);
+ }
}
void MixerCurveWidget::setMin(double value)
@@ -217,6 +270,14 @@ void MixerCurveWidget::setMax(double value)
{
curveMax = value;
}
+double MixerCurveWidget::getMin()
+{
+ return curveMin;
+}
+double MixerCurveWidget::getMax()
+{
+ return curveMax;
+}
void MixerCurveWidget::setRange(double min, double max)
{
curveMin = min;
diff --git a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvewidget.h b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvewidget.h
index 9a14123a7..92c9c3a8c 100644
--- a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvewidget.h
+++ b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvewidget.h
@@ -31,6 +31,7 @@
#include
#include
#include
+#include
#include "mixercurvepoint.h"
#include "mixercurveline.h"
#include "uavobjectwidgetutils_global.h"
@@ -45,12 +46,16 @@ public:
void itemMoved(double itemValue); // Callback when a point is moved, to be updated
void initCurve (QList points);
QList getCurve();
- void initLinearCurve(quint32 numPoints, double maxValue);
+ void initLinearCurve(quint32 numPoints, double maxValue = 1, double minValue = 0);
void setCurve(QList);
void setMin(double value);
+ double getMin();
void setMax(double value);
+ double getMax();
void setRange(double min, double max);
+ static const int NODE_NUMELEM = 5;
+
signals:
void curveUpdated(QList, double );
@@ -58,9 +63,19 @@ private slots:
private:
QGraphicsSvgItem *plot;
+
+ QList nodePool;
+ QList edgePool;
QList nodeList;
+ QList points;
+
double curveMin;
double curveMax;
+ bool curveUpdating;
+
+ void initNodes(int numPoints);
+ Node* getNode(int index);
+ Edge* getEdge(int index, Node* sourceNode, Node* destNode);
protected:
void showEvent(QShowEvent *event);
diff --git a/ground/openpilotgcs/src/plugins/uavtalk/uavtalk.cpp b/ground/openpilotgcs/src/plugins/uavtalk/uavtalk.cpp
index dd0fb21a7..d12d6d9fe 100644
--- a/ground/openpilotgcs/src/plugins/uavtalk/uavtalk.cpp
+++ b/ground/openpilotgcs/src/plugins/uavtalk/uavtalk.cpp
@@ -110,10 +110,12 @@ void UAVTalk::processInputStream()
{
quint8 tmp;
- while (io->bytesAvailable() > 0)
- {
- io->read((char*)&tmp, 1);
- processInputByte(tmp);
+ if (io && io->isReadable()) {
+ while (io->bytesAvailable() > 0)
+ {
+ io->read((char*)&tmp, 1);
+ processInputByte(tmp);
+ }
}
}
@@ -731,9 +733,8 @@ bool UAVTalk::transmitNack(quint32 objId)
qToLittleEndian(dataOffset, &txBuffer[2]);
-
// Send buffer, check that the transmit backlog does not grow above limit
- if ( io->bytesToWrite() < TX_BUFFER_SIZE )
+ if (io && io->isWritable() && io->bytesToWrite() < TX_BUFFER_SIZE )
{
io->write((const char*)txBuffer, dataOffset+CHECKSUM_LENGTH);
}
@@ -823,7 +824,7 @@ bool UAVTalk::transmitSingleObject(UAVObject* obj, quint8 type, bool allInstance
txBuffer[dataOffset+length] = updateCRC(0, txBuffer, dataOffset + length);
// Send buffer, check that the transmit backlog does not grow above limit
- if ( io->bytesToWrite() < TX_BUFFER_SIZE )
+ if (io && io->isWritable() && io->bytesToWrite() < TX_BUFFER_SIZE )
{
io->write((const char*)txBuffer, dataOffset+length+CHECKSUM_LENGTH);
}
diff --git a/ground/openpilotgcs/src/plugins/uavtalk/uavtalk.h b/ground/openpilotgcs/src/plugins/uavtalk/uavtalk.h
index 217f110d9..6f0bf2e8d 100644
--- a/ground/openpilotgcs/src/plugins/uavtalk/uavtalk.h
+++ b/ground/openpilotgcs/src/plugins/uavtalk/uavtalk.h
@@ -27,6 +27,7 @@
#ifndef UAVTALK_H
#define UAVTALK_H
+#include
#include
#include
#include
@@ -100,7 +101,7 @@ private:
typedef enum {STATE_SYNC, STATE_TYPE, STATE_SIZE, STATE_OBJID, STATE_INSTID, STATE_DATA, STATE_CS} RxStateType;
// Variables
- QIODevice* io;
+ QPointer io;
UAVObjectManager* objMngr;
QMutex* mutex;
QMap transMap;