diff --git a/artwork/Dials/README.txt b/artwork/Dials/README.txt
index 1e4e6be4a..54d0f7c90 100644
--- a/artwork/Dials/README.txt
+++ b/artwork/Dials/README.txt
@@ -12,3 +12,6 @@ extracts directory:
TODO: ideally, extracting the layers from the master SVG should be automated, but for now we are doing it manually.
+defaultset directory:
+
+ This directory contains dials which are ready for use in the GCS.
\ No newline at end of file
diff --git a/artwork/Dials/defaultset/attitude.svg b/artwork/Dials/defaultset/attitude.svg
new file mode 100644
index 000000000..6417926f7
--- /dev/null
+++ b/artwork/Dials/defaultset/attitude.svg
@@ -0,0 +1,509 @@
+
+
+
+
diff --git a/artwork/Dials/simpledial-vertical.svg b/artwork/Dials/simpledial-vertical.svg
new file mode 100644
index 000000000..f7c09a326
--- /dev/null
+++ b/artwork/Dials/simpledial-vertical.svg
@@ -0,0 +1,397 @@
+
+
+
+
diff --git a/ground/src/plugins/airspeed/airspeedgadget.cpp b/ground/src/plugins/airspeed/airspeedgadget.cpp
index 23e1e3451..d9e6b9476 100644
--- a/ground/src/plugins/airspeed/airspeedgadget.cpp
+++ b/ground/src/plugins/airspeed/airspeedgadget.cpp
@@ -49,7 +49,8 @@ void AirspeedGadget::loadConfiguration(IUAVGadgetConfiguration* config)
{
AirspeedGadgetConfiguration *m = qobject_cast(config);
m_widget->setDialFile(m->dialFile(), m->dialBackground(), m->dialForeground(), m->dialNeedle1(),
- m->dialNeedle2(),m->getN1Move(), m->getN2Move());
+ m->dialNeedle2(),m->dialNeedle3(),m->getN1Move(), m->getN2Move(),
+ m->getN3Move());
m_widget->setN1Min(m->getN1Min());
m_widget->setN1Max(m->getN1Max());
@@ -57,6 +58,11 @@ void AirspeedGadget::loadConfiguration(IUAVGadgetConfiguration* config)
m_widget->setN2Min(m->getN2Min());
m_widget->setN2Max(m->getN2Max());
m_widget->setN2Factor(m->getN2Factor());
+ m_widget->setN3Min(m->getN3Min());
+ m_widget->setN3Max(m->getN3Max());
+ m_widget->setN3Factor(m->getN3Factor());
m_widget->connectNeedles(m->getN1DataObject(),m->getN1ObjField(),
- m->getN2DataObject(),m->getN2ObjField());
+ m->getN2DataObject(),m->getN2ObjField(),
+ m->getN3DataObject(),m->getN3ObjField()
+ );
}
diff --git a/ground/src/plugins/airspeed/airspeedgadgetconfiguration.cpp b/ground/src/plugins/airspeed/airspeedgadgetconfiguration.cpp
index fefefc360..32870767a 100644
--- a/ground/src/plugins/airspeed/airspeedgadgetconfiguration.cpp
+++ b/ground/src/plugins/airspeed/airspeedgadgetconfiguration.cpp
@@ -39,14 +39,19 @@ AirspeedGadgetConfiguration::AirspeedGadgetConfiguration(QString classId, const
dialForegroundID("foreground"),
dialNeedleID1("needle"),
dialNeedleID2("needle2"),
+ dialNeedleID3("needle3"),
needle1MinValue(0),
needle1MaxValue(100),
needle2MinValue(0),
needle2MaxValue(100),
+ needle3MinValue(0),
+ needle3MaxValue(100),
needle1Factor(1),
needle2Factor(1),
+ needle3Factor(1),
needle1Move("Rotate"),
- needle2Move("Rotate")
+ needle2Move("Rotate"),
+ needle3Move("Rotate")
{
//if a saved configuration exists load it
if (state.count() > 0) {
@@ -58,18 +63,25 @@ AirspeedGadgetConfiguration::AirspeedGadgetConfiguration(QString classId, const
stream >> dialForegroundID;
stream >> dialNeedleID1;
stream >> dialNeedleID2;
+ stream >> dialNeedleID3;
stream >> needle1MinValue;
stream >> needle1MaxValue;
stream >> needle2MinValue;
stream >> needle2MaxValue;
+ stream >> needle3MinValue;
+ stream >> needle3MaxValue;
stream >> needle1DataObject;
stream >> needle1ObjectField;
stream >> needle2DataObject;
stream >> needle2ObjectField;
+ stream >> needle3DataObject;
+ stream >> needle3ObjectField;
stream >> needle1Factor;
stream >> needle2Factor;
+ stream >> needle3Factor;
stream >> needle1Move;
stream >> needle2Move;
+ stream >> needle3Move;
}
}
/**
@@ -95,18 +107,25 @@ QByteArray AirspeedGadgetConfiguration::saveState() const
stream << dialForegroundID;
stream << dialNeedleID1;
stream << dialNeedleID2;
+ stream << dialNeedleID3;
stream << needle1MinValue;
stream << needle1MaxValue;
stream << needle2MinValue;
stream << needle2MaxValue;
+ stream << needle3MinValue;
+ stream << needle3MaxValue;
stream << needle1DataObject;
stream << needle1ObjectField;
stream << needle2DataObject;
stream << needle2ObjectField;
+ stream << needle3DataObject;
+ stream << needle3ObjectField;
stream << needle1Factor;
stream << needle2Factor;
+ stream << needle3Factor;
stream << needle1Move;
stream << needle2Move;
+ stream << needle3Move;
return bytes;
}
diff --git a/ground/src/plugins/airspeed/airspeedgadgetconfiguration.h b/ground/src/plugins/airspeed/airspeedgadgetconfiguration.h
index dbb9f57c2..080b82953 100644
--- a/ground/src/plugins/airspeed/airspeedgadgetconfiguration.h
+++ b/ground/src/plugins/airspeed/airspeedgadgetconfiguration.h
@@ -47,18 +47,25 @@ public:
void setDialForegroundID(QString elementID) { dialForegroundID = elementID;}
void setDialNeedleID1(QString elementID) { dialNeedleID1 = elementID;}
void setDialNeedleID2(QString elementID) { dialNeedleID2 = elementID;}
+ void setDialNeedleID3(QString elementID) { dialNeedleID3 = elementID;}
void setN1Min(double val) { needle1MinValue = val;}
void setN2Min(double val) { needle2MinValue = val;}
+ void setN3Min(double val) { needle3MinValue = val;}
void setN1Max(double val) { needle1MaxValue = val;}
void setN2Max(double val) { needle2MaxValue = val;}
+ void setN3Max(double val) { needle3MaxValue = val;}
void setN1Factor(double val) { needle1Factor = val;}
void setN2Factor(double val) { needle2Factor = val;}
+ void setN3Factor(double val) { needle3Factor = val;}
void setN1DataObject(QString text) {needle1DataObject = text; }
void setN2DataObject(QString text){ needle2DataObject = text; }
+ void setN3DataObject(QString text){ needle3DataObject = text; }
void setN1ObjField(QString text) { needle1ObjectField = text; }
void setN2ObjField(QString text) { needle2ObjectField = text; }
+ void setN3ObjField(QString text) { needle3ObjectField = text; }
void setN1Move( QString move) { needle1Move = move; }
void setN2Move( QString move) { needle2Move = move; }
+ void setN3Move( QString move) { needle3Move = move; }
//get dial configuration functions
QString dialFile() {return m_defaultDial;}
@@ -66,18 +73,25 @@ public:
QString dialForeground() {return dialForegroundID;}
QString dialNeedle1() {return dialNeedleID1;}
QString dialNeedle2() {return dialNeedleID2;}
+ QString dialNeedle3() {return dialNeedleID3;}
double getN1Min() { return needle1MinValue;}
double getN2Min() { return needle2MinValue;}
+ double getN3Min() { return needle3MinValue;}
double getN1Max() { return needle1MaxValue;}
double getN2Max() { return needle2MaxValue;}
+ double getN3Max() { return needle3MaxValue;}
double getN1Factor() { return needle1Factor;}
double getN2Factor() { return needle2Factor;}
+ double getN3Factor() { return needle3Factor;}
QString getN1DataObject() { return needle1DataObject; }
QString getN2DataObject() { return needle2DataObject; }
+ QString getN3DataObject() { return needle3DataObject; }
QString getN1ObjField() { return needle1ObjectField; }
QString getN2ObjField() { return needle2ObjectField; }
+ QString getN3ObjField() { return needle3ObjectField; }
QString getN1Move() { return needle1Move; }
QString getN2Move() { return needle2Move; }
+ QString getN3Move() { return needle3Move; }
QByteArray saveState() const;
IUAVGadgetConfiguration *clone();
@@ -88,23 +102,30 @@ private:
QString dialForegroundID; // ... of the foreground
QString dialNeedleID1; // ... and the first needle
QString dialNeedleID2; // ... and the second
+ QString dialNeedleID3; // ... and the third
// Note: MinValue not used at the moment!
double needle1MinValue; // Value corresponding to a 0 degree angle;
double needle1MaxValue; // Value corresponding to a 360 degree angle;
double needle2MinValue;
double needle2MaxValue;
+ double needle3MinValue;
+ double needle3MaxValue;
double needle1Factor;
double needle2Factor;
+ double needle3Factor;
QString needle1DataObject;
QString needle1ObjectField;
QString needle2DataObject;
QString needle2ObjectField;
+ QString needle3DataObject;
+ QString needle3ObjectField;
// How the two dials move:
QString needle1Move;
QString needle2Move;
+ QString needle3Move;
};
#endif // AIRSPEEDGADGETCONFIGURATION_H
diff --git a/ground/src/plugins/airspeed/airspeedgadgetoptionspage.cpp b/ground/src/plugins/airspeed/airspeedgadgetoptionspage.cpp
index 19e7d1da8..0cf46b887 100644
--- a/ground/src/plugins/airspeed/airspeedgadgetoptionspage.cpp
+++ b/ground/src/plugins/airspeed/airspeedgadgetoptionspage.cpp
@@ -61,6 +61,7 @@ QWidget *AirspeedGadgetOptionsPage::createPage(QWidget *parent)
foreach (UAVDataObject* obj, list) {
options_page->uavObject1->addItem(obj->getName());
options_page->uavObject2->addItem(obj->getName());
+ options_page->uavObject3->addItem(obj->getName());
}
}
@@ -73,20 +74,29 @@ QWidget *AirspeedGadgetOptionsPage::createPage(QWidget *parent)
options_page->moveNeedle2->addItem("Horizontal");
options_page->moveNeedle2->addItem("Vertical");
+ options_page->moveNeedle3->addItem("Rotate");
+ options_page->moveNeedle3->addItem("Horizontal");
+ options_page->moveNeedle3->addItem("Vertical");
+
// Restore the contents from the settings:
options_page->svgSourceFile->setText(m_config->dialFile());
options_page->backgroundID->setText(m_config->dialBackground());
options_page->foregroundID->setText(m_config->dialForeground());
options_page->needle1ID->setText(m_config->dialNeedle1());
options_page->needle2ID->setText(m_config->dialNeedle2());
+ options_page->needle3ID->setText(m_config->dialNeedle3());
options_page->needle1Min->setValue(m_config->getN1Min());
options_page->needle1Max->setValue(m_config->getN1Max());
options_page->needle2Min->setValue(m_config->getN2Min());
options_page->needle2Max->setValue(m_config->getN2Max());
+ options_page->needle3Min->setValue(m_config->getN3Min());
+ options_page->needle3Max->setValue(m_config->getN3Max());
options_page->factor1->setValue(m_config->getN1Factor());
options_page->factor2->setValue(m_config->getN2Factor());
+ options_page->factor3->setValue(m_config->getN3Factor());
options_page->moveNeedle1->setCurrentIndex(options_page->moveNeedle1->findText(m_config->getN1Move()));
options_page->moveNeedle2->setCurrentIndex(options_page->moveNeedle2->findText(m_config->getN2Move()));
+ options_page->moveNeedle3->setCurrentIndex(options_page->moveNeedle3->findText(m_config->getN3Move()));
//select saved UAV Object field values
if(options_page->uavObject1->findText(m_config->getN1DataObject())!=-1){
@@ -103,6 +113,7 @@ QWidget *AirspeedGadgetOptionsPage::createPage(QWidget *parent)
}
}
connect(options_page->uavObject1, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_uavObject1_currentIndexChanged(QString)));
+
if(options_page->uavObject2->findText(m_config->getN2DataObject())!=-1){
options_page->uavObject2->setCurrentIndex(options_page->uavObject2->findText(m_config->getN2DataObject()));
// Now load the object field values:
@@ -116,6 +127,21 @@ QWidget *AirspeedGadgetOptionsPage::createPage(QWidget *parent)
}
}
connect(options_page->uavObject2, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_uavObject2_currentIndexChanged(QString)));
+
+ if(options_page->uavObject3->findText(m_config->getN3DataObject())!=-1){
+ options_page->uavObject3->setCurrentIndex(options_page->uavObject3->findText(m_config->getN3DataObject()));
+ // Now load the object field values:
+ UAVDataObject* obj = dynamic_cast( objManager->getObject(m_config->getN3DataObject()));
+ if (obj != NULL ) {
+ QList fieldList = obj->getFields();
+ foreach (UAVObjectField* field, fieldList) {
+ options_page->objectField3->addItem(field->getName());
+ }
+ options_page->objectField3->setCurrentIndex(options_page->objectField3->findText(m_config->getN3ObjField()));
+ }
+ }
+ connect(options_page->uavObject3, SIGNAL(currentIndexChanged(QString)), this, SLOT(on_uavObject3_currentIndexChanged(QString)));
+
connect(options_page->loadFile, SIGNAL(clicked()), this, SLOT(on_loadFile_clicked()));
return optionsPageWidget;
}
@@ -133,18 +159,25 @@ void AirspeedGadgetOptionsPage::apply()
m_config->setDialForegroundID(options_page->foregroundID->text());
m_config->setDialNeedleID1(options_page->needle1ID->text());
m_config->setDialNeedleID2(options_page->needle2ID->text());
+ m_config->setDialNeedleID3(options_page->needle3ID->text());
m_config->setN1Min(options_page->needle1Min->value());
m_config->setN1Max(options_page->needle1Max->value());
m_config->setN1Factor(options_page->factor1->value());
m_config->setN2Min(options_page->needle2Min->value());
m_config->setN2Max(options_page->needle2Max->value());
m_config->setN2Factor(options_page->factor2->value());
+ m_config->setN3Min(options_page->needle3Min->value());
+ m_config->setN3Max(options_page->needle3Max->value());
+ m_config->setN3Factor(options_page->factor3->value());
m_config->setN1DataObject(options_page->uavObject1->currentText());
m_config->setN2DataObject(options_page->uavObject2->currentText());
+ m_config->setN3DataObject(options_page->uavObject3->currentText());
m_config->setN1ObjField(options_page->objectField1->currentText());
m_config->setN2ObjField(options_page->objectField2->currentText());
+ m_config->setN3ObjField(options_page->objectField3->currentText());
m_config->setN1Move(options_page->moveNeedle1->currentText());
m_config->setN2Move(options_page->moveNeedle2->currentText());
+ m_config->setN3Move(options_page->moveNeedle3->currentText());
}
/*
@@ -164,7 +197,7 @@ void AirspeedGadgetOptionsPage::on_uavObject1_currentIndexChanged(QString val) {
/*
Fills in the field2 combo box when value is changed in the
- object1 field
+ object2 field
*/
void AirspeedGadgetOptionsPage::on_uavObject2_currentIndexChanged(QString val) {
options_page->objectField2->clear();
@@ -177,6 +210,21 @@ void AirspeedGadgetOptionsPage::on_uavObject2_currentIndexChanged(QString val) {
}
}
+/*
+ Fills in the field3 combo box when value is changed in the
+ object3 field
+*/
+void AirspeedGadgetOptionsPage::on_uavObject3_currentIndexChanged(QString val) {
+ options_page->objectField3->clear();
+ ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
+ UAVObjectManager *objManager = pm->getObject();
+ UAVDataObject* obj = dynamic_cast( objManager->getObject(val) );
+ QList fieldList = obj->getFields();
+ foreach (UAVObjectField* field, fieldList) {
+ options_page->objectField3->addItem(field->getName());
+ }
+}
+
/*
Opens an open file dialog.
diff --git a/ground/src/plugins/airspeed/airspeedgadgetoptionspage.h b/ground/src/plugins/airspeed/airspeedgadgetoptionspage.h
index a91805fa4..4872e5eeb 100644
--- a/ground/src/plugins/airspeed/airspeedgadgetoptionspage.h
+++ b/ground/src/plugins/airspeed/airspeedgadgetoptionspage.h
@@ -63,6 +63,7 @@ private slots:
void on_loadFile_clicked();
void on_uavObject1_currentIndexChanged(QString val);
void on_uavObject2_currentIndexChanged(QString val);
+ void on_uavObject3_currentIndexChanged(QString val);
};
#endif // AIRSPEEDGADGETOPTIONSPAGE_H
diff --git a/ground/src/plugins/airspeed/airspeedgadgetoptionspage.ui b/ground/src/plugins/airspeed/airspeedgadgetoptionspage.ui
index 840e59e2b..dd37fac11 100644
--- a/ground/src/plugins/airspeed/airspeedgadgetoptionspage.ui
+++ b/ground/src/plugins/airspeed/airspeedgadgetoptionspage.ui
@@ -7,7 +7,7 @@
0
0
487
- 326
+ 346
@@ -24,11 +24,11 @@
-1
-1
- 481
- 354
+ 504
+ 331
-
+
QLayout::SetMinimumSize
@@ -106,414 +106,647 @@
-
-
-
- Qt::Horizontal
+
+
+ 2
+
+
+ Indicator 1
+
+
+
+
+ 0
+ 10
+ 471
+ 110
+
+
+
+
+ 4
+
+
+ 0
+
+
+ 4
+
+
-
+
+
-
+
+
+ Indicator 1
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Movement:
+
+
+
+ -
+
+
+ -
+
+
+ ID:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+
+
+ -
+
+
+ 10
+
+
-
+
+
+ Min:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 3
+
+
+ -100000.000000000000000
+
+
+ 100000.000000000000000
+
+
+
+ -
+
+
+ Max:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 3
+
+
+ -100000.000000000000000
+
+
+ 100000.000000000000000
+
+
+
+ -
+
+
+ Factor:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ -100000.000000000000000
+
+
+ 100000.000000000000000
+
+
+
+
+
+ -
+
+
+ 10
+
+
-
+
+
+ DataObject
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ ObjectField
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+
+
+ Indicator 2
+
+
+
+
+ 0
+ 10
+ 471
+ 116
+
+
+
+
+ 0
+
+
+ 4
+
+ -
+
+
-
+
+
+ Indicator 2
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Movement:
+
+
+
+ -
+
+
+ -
+
+
+ ID:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ -
+
+
+ 10
+
+
-
+
+
+ Min:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 3
+
+
+ -10000.000000000000000
+
+
+ 100000.000000000000000
+
+
+
+ -
+
+
+ Max:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 3
+
+
+ -100000.000000000000000
+
+
+ 100000.000000000000000
+
+
+
+ -
+
+
+ Factor:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ -100000.000000000000000
+
+
+ 100000.000000000000000
+
+
+
+
+
+ -
+
+
+ 10
+
+
-
+
+
+ DataObject
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ ObjectField
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+
+
+ Indicator 3
+
+
+
+
+ 0
+ 10
+ 471
+ 116
+
+
+
+
+ 0
+
+
+ 4
+
+ -
+
+
-
+
+
+ Indicator 3
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Movement:
+
+
+
+ -
+
+
+ -
+
+
+ ID:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ -
+
+
+ 10
+
+
-
+
+
+ Min:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 3
+
+
+ -10000.000000000000000
+
+
+ 100000.000000000000000
+
+
+
+ -
+
+
+ Max:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 3
+
+
+ -100000.000000000000000
+
+
+ 100000.000000000000000
+
+
+
+ -
+
+
+ Factor:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ -100000.000000000000000
+
+
+ 100000.000000000000000
+
+
+
+
+
+ -
+
+
+ 10
+
+
-
+
+
+ DataObject
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ ObjectField
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+
+
- -
-
-
- 4
-
-
- 0
-
-
- 10
-
-
-
-
-
-
-
-
- Indicator 1
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- Movement:
-
-
-
- -
-
-
- -
-
-
- ID:
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 50
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- -
-
-
- 10
-
-
-
-
-
- Min:
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- 3
-
-
- -100000.000000000000000
-
-
- 100000.000000000000000
-
-
-
- -
-
-
- Max:
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- 3
-
-
- -100000.000000000000000
-
-
- 100000.000000000000000
-
-
-
- -
-
-
- Factor:
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- -100000.000000000000000
-
-
- 100000.000000000000000
-
-
-
-
-
- -
-
-
- 10
-
-
-
-
-
- DataObject
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- -
-
-
- ObjectField
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
-
-
- -
-
-
- 0
-
-
- 10
-
-
-
-
-
-
-
-
- Indicator 2
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- Movement:
-
-
-
- -
-
-
- -
-
-
- ID:
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
-
-
- -
-
-
- 10
-
-
-
-
-
- Min:
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- 3
-
-
- -10000.000000000000000
-
-
- 100000.000000000000000
-
-
-
- -
-
-
- Max:
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- 3
-
-
- -100000.000000000000000
-
-
- 100000.000000000000000
-
-
-
- -
-
-
- Factor:
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- -100000.000000000000000
-
-
- 100000.000000000000000
-
-
-
-
-
- -
-
-
- 10
-
-
-
-
-
- DataObject
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- -
-
-
- ObjectField
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
-
-
-
Qt::Vertical
+
+ QSizePolicy::Minimum
+
20
@@ -522,6 +755,13 @@
+ -
+
+
+ Qt::Horizontal
+
+
+
diff --git a/ground/src/plugins/airspeed/airspeedgadgetwidget.cpp b/ground/src/plugins/airspeed/airspeedgadgetwidget.cpp
index 0626bdb5a..5cc60ec58 100644
--- a/ground/src/plugins/airspeed/airspeedgadgetwidget.cpp
+++ b/ground/src/plugins/airspeed/airspeedgadgetwidget.cpp
@@ -28,31 +28,35 @@
#include "airspeedgadgetwidget.h"
#include
#include
-#include "math.h"
AirspeedGadgetWidget::AirspeedGadgetWidget(QWidget *parent) : QGraphicsView(parent)
{
+ // TODO: create a proper "needle" object instead of hardcoding all this
+ // which is ugly (but easy).
+
setMinimumSize(64,64);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setScene(new QGraphicsScene(this));
+
m_renderer = new QSvgRenderer();
m_background = new QGraphicsSvgItem();
m_foreground = new QGraphicsSvgItem();
m_needle1 = new QGraphicsSvgItem();
m_needle2 = new QGraphicsSvgItem();
+ m_needle3 = new QGraphicsSvgItem();
paint();
needle1Target = 0;
needle2Target = 0;
+ needle3Target = 0;
needle1Value = 0;
needle2Value = 0;
+ needle3Value = 0;
obj1 = NULL;
obj2 = NULL;
-
- rotateN1 = horizN1 = vertN1 = false;
- rotateN2 = horizN2 = vertN2 = false;
+ obj3 = NULL;
// This timer mechanism makes needles rotate smoothly
connect(&dialTimer, SIGNAL(timeout()), this, SLOT(rotateNeedles()));
@@ -68,15 +72,18 @@ AirspeedGadgetWidget::~AirspeedGadgetWidget()
/*!
\brief Connects the widget to the relevant UAVObjects
*/
-void AirspeedGadgetWidget::connectNeedles(QString object1, QString nfield1, QString object2, QString nfield2 ) {
+void AirspeedGadgetWidget::connectNeedles(QString object1, QString nfield1,
+ QString object2, QString nfield2,
+ QString object3, QString nfield3) {
if (obj1 != NULL)
disconnect(obj1,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(updateNeedle1(UAVObject*)));
if (obj2 != NULL)
disconnect(obj2,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(updateNeedle2(UAVObject*)));
+ if (obj3 != NULL)
+ disconnect(obj3,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(updateNeedle3(UAVObject*)));
+
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject();
- std::cout << "Connect needles - " << object1.toStdString() << "-"<< nfield1.toStdString() << " - " <<
- object2.toStdString() << "-" << nfield2.toStdString() << std::endl;
// Check validity of arguments first, reject empty args and unknown fields.
if (!(object1.isEmpty() || nfield1.isEmpty())) {
@@ -101,6 +108,18 @@ void AirspeedGadgetWidget::connectNeedles(QString object1, QString nfield1, QStr
std::cout << "Error: Object is unknown (" << object2.toStdString() << ")." << std::endl;
}
}
+
+ // And do the same for the third needle.
+ if (!(object3.isEmpty() || nfield3.isEmpty())) {
+ obj3 = dynamic_cast( objManager->getObject(object3) );
+ if (obj3 != NULL ) {
+ std::cout << "Connected Object 3 (" << object3.toStdString() << ")." << std::endl;
+ connect(obj3, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateNeedle3(UAVObject*)));
+ field3 = nfield3;
+ } else {
+ std::cout << "Error: Object is unknown (" << object3.toStdString() << ")." << std::endl;
+ }
+ }
}
/*!
@@ -114,7 +133,6 @@ void AirspeedGadgetWidget::updateNeedle1(UAVObject *object1) {
} else {
std::cout << "Wrong field, maybe an issue with object disconnection ?" << std::endl;
}
- std::cout << "Update Needle 1 with value of field " << field1.toStdString() << std::endl;
}
/*!
@@ -129,8 +147,24 @@ void AirspeedGadgetWidget::updateNeedle2(UAVObject *object2) {
}
}
+/*!
+ \brief Called by the UAVObject which got updated
+ */
+void AirspeedGadgetWidget::updateNeedle3(UAVObject *object3) {
+ UAVObjectField* field = object3->getField(field3);
+ if (field) {
+ setNeedle3(field->getDouble());
+ } else {
+ std::cout << "Wrong field, maybe an issue with object disconnection ?" << std::endl;
+ }
+}
+
+/*
+ Initializes the dial file, and does all the one-time calculations for
+ display later.
+ */
void AirspeedGadgetWidget::setDialFile(QString dfn, QString bg, QString fg, QString n1, QString n2,
- QString n1Move, QString n2Move)
+ QString n3, QString n1Move, QString n2Move, QString n3Move)
{
if (QFile::exists(dfn))
{
@@ -139,25 +173,28 @@ void AirspeedGadgetWidget::setDialFile(QString dfn, QString bg, QString fg, QStr
{
fgenabled = false;
n2enabled = false;
+ n3enabled = false;
QGraphicsScene *l_scene = scene();
+ l_scene->removeItem(m_foreground);
+ l_scene->removeItem(m_background);
+ l_scene->removeItem(m_needle1);
+ l_scene->removeItem(m_needle2);
+ l_scene->removeItem(m_needle3);
+ // We assume the scene contains at least the background
+ // and needle1
m_background->setSharedRenderer(m_renderer);
m_background->setElementId(bg);
+ l_scene->addItem(m_background);
+
m_needle1->setSharedRenderer(m_renderer);
m_needle1->setElementId(n1);
+ l_scene->addItem(m_needle1);
- if (m_renderer->elementExists(fg)) {
- m_foreground->setSharedRenderer(m_renderer);
- m_foreground->setElementId(fg);
- if (!l_scene->items().contains(m_foreground))
- l_scene->addItem(m_foreground);
- fgenabled = true;
- } else {
- if (l_scene->items().contains(m_foreground))
- l_scene->removeItem(m_foreground);
- fgenabled = false;
- }
+ // The dial gadget allows Needle1 and Needle2 to be
+ // the same element, for combined movement. Needle3
+ // is always independent.
if (n1 == n2) {
m_needle2 = m_needle1;
n2enabled = true;
@@ -165,15 +202,35 @@ void AirspeedGadgetWidget::setDialFile(QString dfn, QString bg, QString fg, QStr
if (m_renderer->elementExists(n2)) {
m_needle2->setSharedRenderer(m_renderer);
m_needle2->setElementId(n2);
- if (!l_scene->items().contains(m_needle2))
- l_scene->addItem(m_needle2);
+ l_scene->addItem(m_needle2);
n2enabled = true;
- } else {
- if (l_scene->items().contains(m_needle2))
- l_scene->removeItem(m_needle2);
- n2enabled = false;
+ }
}
- }
+
+ if (m_renderer->elementExists(n3)) {
+ m_needle3->setSharedRenderer(m_renderer);
+ m_needle3->setElementId(n3);
+ l_scene->addItem(m_needle3);
+ n3enabled = true;
+ }
+
+ if (m_renderer->elementExists(fg)) {
+ m_foreground->setSharedRenderer(m_renderer);
+ m_foreground->setElementId(fg);
+ l_scene->addItem(m_foreground);
+ fgenabled = true;
+ }
+
+ rotateN1 = false;
+ horizN1 = false;
+ vertN1 = false;
+ rotateN2 = false;
+ horizN2 = false;
+ vertN2 = false;
+ rotateN3 = false;
+ horizN3 = false;
+ vertN3 = false;
+
// Now setup the rotation/translation settings:
// this is UGLY UGLY UGLY, sorry...
@@ -193,17 +250,37 @@ void AirspeedGadgetWidget::setDialFile(QString dfn, QString bg, QString fg, QStr
vertN2 = true;
}
- // std::cout<<"Dial file loaded ("<< dfn.toStdString() << ")" << std::endl;
- l_scene->setSceneRect(m_background->boundingRect());
+ if (n3Move.contains("Rotate")) {
+ rotateN3 = true;
+ } else if (n3Move.contains("Horizontal")) {
+ horizN3 = true;
+ } else if (n3Move.contains("Vertical")) {
+ vertN3 = true;
+ }
- // Initialize the center for all transforms of the dials to the
+ l_scene->setSceneRect(m_background->boundingRect());
+ // Now Initialize the center for all transforms of the dial needles to the
// center of the background:
- QRectF rect1 = m_background->boundingRect();
- QPointF tr1 = m_background->mapToScene(rect1.width()/2,rect1.height()/2);
- QPointF tr = m_needle1->mapFromScene(tr1);
- m_needle1->setTransformOriginPoint(tr.x(),tr.y());
- tr = m_needle2->mapFromScene(tr1);
- m_needle2->setTransformOriginPoint(tr.x(),tr.y());
+ // - Move the center of the needle to the center of the background.
+ QRectF rectB = m_background->boundingRect();
+ QRectF rectN = m_needle1->boundingRect();
+ m_needle1->setPos(rectB.width()/2-rectN.width()/2,rectB.height()/2-rectN.height()/2);
+ // - Put the transform origin point of the needle at its center.
+ m_needle1->setTransformOriginPoint(rectN.width()/2,rectN.height()/2);
+ if ((n1 != n2) && n2enabled) {
+ // Only do it for needle1 if it is not the same as n2
+ rectN = m_needle2->boundingRect();
+ m_needle2->setPos(rectB.width()/2-rectN.width()/2,rectB.height()/2-rectN.height()/2);
+ m_needle2->setTransformOriginPoint(rectN.width()/2,rectN.height()/2);
+ }
+ if (n3enabled) {
+ rectN = m_needle3->boundingRect();
+ m_needle3->setPos(rectB.width()/2-rectN.width()/2,rectB.height()/2-rectN.height()/2);
+ m_needle3->setTransformOriginPoint(rectN.width()/2,rectN.height()/2);
+ }
+
+ // Last: clip the display region to the rectangle of the background
+ // TODO
}
}
else
@@ -217,6 +294,7 @@ void AirspeedGadgetWidget::paint()
l_scene->addItem(m_background);
l_scene->addItem(m_needle1);
l_scene->addItem(m_needle2);
+ l_scene->addItem(m_needle3);
l_scene->addItem(m_foreground);
l_scene->setSceneRect(m_background->boundingRect());
update();
@@ -266,6 +344,18 @@ void AirspeedGadgetWidget::setNeedle2(double value) {
}
}
+void AirspeedGadgetWidget::setNeedle3(double value) {
+ if (rotateN3) {
+ needle3Target = 360*value*n3Factor/(n3MaxValue-n3MinValue);
+ }
+ if (horizN3) {
+ needle3Target = value*n3Factor/(n3MaxValue-n3MinValue);
+ }
+ if (vertN3) {
+ needle3Target = value*n3Factor/(n3MaxValue-n3MinValue);
+ }
+}
+
// Take an input value and rotate the dial accordingly
// Rotation is smooth, starts fast and slows down when
// approaching the target.
@@ -275,6 +365,9 @@ void AirspeedGadgetWidget::setNeedle2(double value) {
// to the same element.
void AirspeedGadgetWidget::rotateNeedles()
{
+ // TODO: watch out of potential drift of needles due to
+ // rounding errors. Should implement a way to set the value
+ // exactly to the target once it falls below the threshold.
if ((abs((needle2Value-needle2Target)*10) > 5) && n2enabled) {
double needle2Diff;
needle2Diff =(needle2Target - needle2Value)/5;
@@ -293,7 +386,7 @@ void AirspeedGadgetWidget::rotateNeedles()
// the transform origin point the opposite way
// so that it keeps rotating from the same point.
// (this is only useful if needle1 and needle2 are the
- // same object, for combined movement.
+ // same object, for combined movement such as attitude indicator).
QPointF oop = m_needle2->transformOriginPoint();
m_needle2->setTransformOriginPoint(oop.x()-opd.x(),oop.y()-opd.y());
}
@@ -320,6 +413,25 @@ void AirspeedGadgetWidget::rotateNeedles()
needle1Value += needle1Diff;
}
+ if ((abs((needle3Value-needle3Target)*10) > 5)) {
+ double needle3Diff;
+ needle3Diff = (needle3Target - needle3Value)/5;
+ if (rotateN3) {
+ m_needle3->setRotation(m_needle3->rotation()+needle3Diff);
+ } else {
+ QPointF opd = QPointF(0,0);
+ if (horizN3) {
+ opd = QPointF(needle3Diff,0);
+ }
+ if (vertN3) {
+ opd = QPointF(0,needle3Diff);
+ }
+ m_needle3->setTransform(QTransform::fromTranslate(opd.x(),opd.y()), true);
+ QPointF oop = m_needle3->transformOriginPoint();
+ m_needle3->setTransformOriginPoint((oop.x()-opd.x()),(oop.y()-opd.y()));
+ }
+ needle3Value += needle3Diff;
+ }
+
update();
}
-
diff --git a/ground/src/plugins/airspeed/airspeedgadgetwidget.h b/ground/src/plugins/airspeed/airspeedgadgetwidget.h
index c91ef98be..e7a1f6e91 100644
--- a/ground/src/plugins/airspeed/airspeedgadgetwidget.h
+++ b/ground/src/plugins/airspeed/airspeedgadgetwidget.h
@@ -46,26 +46,32 @@ class AirspeedGadgetWidget : public QGraphicsView
public:
AirspeedGadgetWidget(QWidget *parent = 0);
~AirspeedGadgetWidget();
- void setDialFile(QString dfn, QString bg, QString fg, QString n1, QString n2, QString n1Move,
- QString n2Move);
+ void setDialFile(QString dfn, QString bg, QString fg, QString n1, QString n2, QString n3,
+ QString n1Move, QString n2Move, QString n3Move);
void paint();
// setNeedle1 and setNeedle2 use a timer to simulate
// needle inertia
void setNeedle1(double value);
void setNeedle2(double value);
+ void setNeedle3(double value);
void setN1Min(double value) {n1MinValue = value;}
void setN1Max(double value) {n1MaxValue = value;}
void setN1Factor(double value) {n1Factor = value;}
void setN2Min(double value) {n2MinValue = value;}
void setN2Max(double value) {n2MaxValue = value;}
void setN2Factor(double value) {n2Factor = value;}
+ void setN3Min(double value) {n3MinValue = value;}
+ void setN3Max(double value) {n3MaxValue = value;}
+ void setN3Factor(double value) {n3Factor = value;}
// Sets up needle/UAVObject connections:
void connectNeedles(QString object1, QString field1,
- QString object2, QString field2);
+ QString object2, QString field2,
+ QString object3, QString field3);
public slots:
void updateNeedle1(UAVObject *object1); // Called by the UAVObject
void updateNeedle2(UAVObject *object2); // Called by the UAVObject
+ void updateNeedle3(UAVObject *object3); // Called by the UAVObject
protected:
void paintEvent(QPaintEvent *event);
@@ -81,17 +87,22 @@ private:
QGraphicsSvgItem *m_foreground;
QGraphicsSvgItem *m_needle1;
QGraphicsSvgItem *m_needle2;
+ QGraphicsSvgItem *m_needle3;
+ bool n3enabled;
bool n2enabled; // Simple flag to skip rendering if the
bool fgenabled; // layer does not exist.
// Settings concerning move of the dials
bool rotateN1;
bool rotateN2;
+ bool rotateN3;
bool horizN1;
bool horizN2;
+ bool horizN3;
bool vertN1;
bool vertN2;
+ bool vertN3;
double n1MinValue;
double n1MaxValue;
@@ -99,6 +110,9 @@ private:
double n2MinValue;
double n2MaxValue;
double n2Factor;
+ double n3MinValue;
+ double n3MaxValue;
+ double n3Factor;
// The Value and target variables
// are expressed in degrees
@@ -106,12 +120,16 @@ private:
double needle1Value;
double needle2Target;
double needle2Value;
+ double needle3Target;
+ double needle3Value;
// Name of the fields to read when an update is received:
UAVDataObject* obj1;
UAVDataObject* obj2;
+ UAVDataObject* obj3;
QString field1;
QString field2;
+ QString field3;
// Rotation timer
QTimer dialTimer;