1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

Smooth and fast needle rotation, using timers. The only remaining thing is to do the actual connection to UAV Objects - everything is in place, configuration-wise.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@575 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
edouard 2010-05-03 05:59:41 +00:00 committed by edouard
parent 5ad8ab3de7
commit 2dc5e416ac
6 changed files with 78 additions and 16 deletions

View File

@ -55,4 +55,6 @@ void AirspeedGadget::loadConfiguration(IUAVGadgetConfiguration* config)
m_widget->setN1Max(m->getN1Max()); m_widget->setN1Max(m->getN1Max());
m_widget->setN2Min(m->getN2Min()); m_widget->setN2Min(m->getN2Min());
m_widget->setN2Max(m->getN2Max()); m_widget->setN2Max(m->getN2Max());
m_widget->connectNeedles(m->getN1DataObject(),m->getN1ObjField(),
m->getN2DataObject(),m->getN2ObjField());
} }

View File

@ -58,6 +58,10 @@ AirspeedGadgetConfiguration::AirspeedGadgetConfiguration(QString classId, const
stream >> needle1MaxValue; stream >> needle1MaxValue;
stream >> needle2MinValue; stream >> needle2MinValue;
stream >> needle2MaxValue; stream >> needle2MaxValue;
stream >> needle1DataObject;
stream >> needle1ObjectField;
stream >> needle2DataObject;
stream >> needle2ObjectField;
} }
} }
@ -88,5 +92,10 @@ QByteArray AirspeedGadgetConfiguration::saveState() const
stream << needle1MaxValue; stream << needle1MaxValue;
stream << needle2MinValue; stream << needle2MinValue;
stream << needle2MaxValue; stream << needle2MaxValue;
stream << needle1DataObject;
stream << needle1ObjectField;
stream << needle2DataObject;
stream << needle2ObjectField;
return bytes; return bytes;
} }

View File

@ -51,6 +51,10 @@ public:
void setN2Min(double val) { needle2MinValue = val;} void setN2Min(double val) { needle2MinValue = val;}
void setN1Max(double val) { needle1MaxValue = val;} void setN1Max(double val) { needle1MaxValue = val;}
void setN2Max(double val) { needle2MaxValue = val;} void setN2Max(double val) { needle2MaxValue = val;}
void setN1DataObject(QString text) {needle1DataObject = text; }
void setN2DataObject(QString text){ needle2DataObject = text; }
void setN1ObjField(QString text) { needle1ObjectField = text; }
void setN2ObjField(QString text) { needle2ObjectField = text; }
//get dial configuration functions //get dial configuration functions
QString dialFile() {return m_defaultDial;} QString dialFile() {return m_defaultDial;}
@ -62,6 +66,12 @@ public:
double getN2Min() { return needle2MinValue;} double getN2Min() { return needle2MinValue;}
double getN1Max() { return needle1MaxValue;} double getN1Max() { return needle1MaxValue;}
double getN2Max() { return needle2MaxValue;} double getN2Max() { return needle2MaxValue;}
QString getN1DataObject() { return needle1DataObject; }
QString getN2DataObject() { return needle2DataObject; }
QString getN1ObjField() { return needle1ObjectField; }
QString getN2ObjField() { return needle2ObjectField; }
QByteArray saveState() const; QByteArray saveState() const;
IUAVGadgetConfiguration *clone(); IUAVGadgetConfiguration *clone();
@ -72,12 +82,17 @@ private:
QString dialForegroundID; // ... of the foreground QString dialForegroundID; // ... of the foreground
QString dialNeedleID1; // ... and the first needle QString dialNeedleID1; // ... and the first needle
QString dialNeedleID2; // ... and the second QString dialNeedleID2; // ... and the second
// TODO: define additional elements such as secondary needle
// Note: MinValue not used at the moment!
double needle1MinValue; // Value corresponding to a 0 degree angle; double needle1MinValue; // Value corresponding to a 0 degree angle;
double needle1MaxValue; // Value corresponding to a 360 degree angle; double needle1MaxValue; // Value corresponding to a 360 degree angle;
double needle2MinValue; double needle2MinValue;
double needle2MaxValue; double needle2MaxValue;
QString needle1DataObject;
QString needle1ObjectField;
QString needle2DataObject;
QString needle2ObjectField;
}; };
#endif // AIRSPEEDGADGETCONFIGURATION_H #endif // AIRSPEEDGADGETCONFIGURATION_H

View File

@ -59,6 +59,10 @@ QWidget *AirspeedGadgetOptionsPage::createPage(QWidget *parent)
options_page->needle1Max->setValue(m_config->getN1Max()); options_page->needle1Max->setValue(m_config->getN1Max());
options_page->needle2Min->setValue(m_config->getN2Min()); options_page->needle2Min->setValue(m_config->getN2Min());
options_page->needle2Max->setValue(m_config->getN2Max()); options_page->needle2Max->setValue(m_config->getN2Max());
options_page->uavObject1->setText(m_config->getN1DataObject());
options_page->uavObject2->setText(m_config->getN2DataObject());
options_page->objectField1->setText(m_config->getN1ObjField());
options_page->objectField2->setText(m_config->getN2ObjField());
connect(options_page->loadFile, SIGNAL(clicked()), this, SLOT(on_loadFile_clicked())); connect(options_page->loadFile, SIGNAL(clicked()), this, SLOT(on_loadFile_clicked()));
@ -82,6 +86,10 @@ void AirspeedGadgetOptionsPage::apply()
m_config->setN1Max(options_page->needle1Max->value()); m_config->setN1Max(options_page->needle1Max->value());
m_config->setN2Min(options_page->needle2Min->value()); m_config->setN2Min(options_page->needle2Min->value());
m_config->setN2Max(options_page->needle2Max->value()); m_config->setN2Max(options_page->needle2Max->value());
m_config->setN1DataObject(options_page->uavObject1->text());
m_config->setN2DataObject(options_page->uavObject2->text());
m_config->setN1ObjField(options_page->objectField1->text());
m_config->setN2ObjField(options_page->objectField2->text());
} }

View File

@ -49,6 +49,7 @@ AirspeedGadgetWidget::AirspeedGadgetWidget(QWidget *parent) : QGraphicsView(pare
needle1Value = 0; needle1Value = 0;
needle2Value = 0; needle2Value = 0;
// This timer mechanism makes needles rotate smoothly
connect(&dialTimer, SIGNAL(timeout()), this, SLOT(rotateNeedles())); connect(&dialTimer, SIGNAL(timeout()), this, SLOT(rotateNeedles()));
dialTimer.start(30); dialTimer.start(30);
@ -63,6 +64,12 @@ AirspeedGadgetWidget::~AirspeedGadgetWidget()
// Do nothing // Do nothing
} }
void AirspeedGadgetWidget::connectNeedles(QString object1, QString field1, QString object2, QString field2 ) {
}
void AirspeedGadgetWidget::setDialFile(QString dfn, QString bg, QString fg, QString n1, QString n2) void AirspeedGadgetWidget::setDialFile(QString dfn, QString bg, QString fg, QString n1, QString n2)
{ {
if (QFile::exists(dfn)) if (QFile::exists(dfn))
@ -70,19 +77,25 @@ void AirspeedGadgetWidget::setDialFile(QString dfn, QString bg, QString fg, QStr
m_renderer->load(dfn); m_renderer->load(dfn);
if(m_renderer->isValid()) if(m_renderer->isValid())
{ {
fgenabled = false;
n2enabled = false;
m_background->setSharedRenderer(m_renderer); m_background->setSharedRenderer(m_renderer);
m_background->setElementId(bg); m_background->setElementId(bg);
m_foreground->setSharedRenderer(m_renderer);
m_foreground->setElementId(fg);
m_needle1->setSharedRenderer(m_renderer); m_needle1->setSharedRenderer(m_renderer);
m_needle1->setElementId(n1); m_needle1->setElementId(n1);
m_needle2->setSharedRenderer(m_renderer); if (m_renderer->elementExists(fg)) {
m_needle2->setElementId(n2); m_foreground->setSharedRenderer(m_renderer);
m_foreground->setElementId(fg);
fgenabled = true;
}
if (m_renderer->elementExists(n2)) {
m_needle2->setSharedRenderer(m_renderer);
m_needle2->setElementId(n2);
n2enabled = true;
}
std::cout<<"Dial file loaded"<<std::endl; std::cout<<"Dial file loaded"<<std::endl;
QGraphicsScene *l_scene = scene(); QGraphicsScene *l_scene = scene();
@ -102,6 +115,7 @@ void AirspeedGadgetWidget::paint()
l_scene->addItem(m_background); l_scene->addItem(m_background);
l_scene->addItem(m_needle1); l_scene->addItem(m_needle1);
l_scene->addItem(m_needle2); l_scene->addItem(m_needle2);
l_scene->addItem(m_foreground); l_scene->addItem(m_foreground);
@ -113,7 +127,7 @@ void AirspeedGadgetWidget::paintEvent(QPaintEvent *event)
{ {
// Skip painting until the dial file is loaded // Skip painting until the dial file is loaded
if (! m_renderer->isValid()) { if (! m_renderer->isValid()) {
std::cout<<"Dial file not loaded"<<std::endl; std::cout<<"Dial file not loaded, not rendering"<<std::endl;
return; return;
} }
QGraphicsView::paintEvent(event); QGraphicsView::paintEvent(event);
@ -127,33 +141,38 @@ void AirspeedGadgetWidget::resizeEvent(QResizeEvent *event)
fitInView(m_background, Qt::KeepAspectRatio ); fitInView(m_background, Qt::KeepAspectRatio );
} }
// Converts the value into an angle:
// this enables smooth rotation in rotateNeedles below
void AirspeedGadgetWidget::setNeedle1(double value) { void AirspeedGadgetWidget::setNeedle1(double value) {
needle1Target = value; needle1Target = 360*value/n1MaxValue;
} }
void AirspeedGadgetWidget::setNeedle2(double value) { void AirspeedGadgetWidget::setNeedle2(double value) {
needle2Target = value; needle2Target = 360*value/n2MaxValue;
} }
// Take an input value and rotate the dial accordingly // Take an input value and rotate the dial accordingly
// Rotation is smooth, starts fast and slows down when
// approaching the target.
// We aim for a 0.5 degree precision.
void AirspeedGadgetWidget::rotateNeedles() void AirspeedGadgetWidget::rotateNeedles()
{ {
if (needle2Value != needle2Target) { if ((abs((needle2Value-needle2Target)*10) > 5) && n2enabled) {
(needle2Value > needle2Target) ? needle2Value-- : needle2Value++; needle2Value+=(needle2Target - needle2Value)/10;
m_needle2->resetTransform(); m_needle2->resetTransform();
QRectF rect = m_needle2->boundingRect(); QRectF rect = m_needle2->boundingRect();
m_needle2->translate(rect.width()/2,rect.height()/2); m_needle2->translate(rect.width()/2,rect.height()/2);
m_needle2->rotate(360*needle2Value/n2MaxValue); m_needle2->rotate(needle2Value);
m_needle2->translate(-rect.width()/2,-rect.height()/2); m_needle2->translate(-rect.width()/2,-rect.height()/2);
} }
if (needle1Value != needle1Target) { if ((abs((needle1Value-needle1Target)*10) > 5)) {
(needle1Value > needle1Target) ? needle1Value-- : needle1Value++; needle1Value += (needle1Target - needle1Value)/10;
m_needle1->resetTransform(); m_needle1->resetTransform();
QRectF rect = m_needle1->boundingRect(); QRectF rect = m_needle1->boundingRect();
m_needle1->translate(rect.width()/2,rect.height()/2); m_needle1->translate(rect.width()/2,rect.height()/2);
m_needle1->rotate(360*needle1Value/n1MaxValue); m_needle1->rotate(needle1Value);
m_needle1->translate(-rect.width()/2,-rect.height()/2); m_needle1->translate(-rect.width()/2,-rect.height()/2);
} }

View File

@ -54,6 +54,9 @@ public:
void setN1Max(double value) {n1MaxValue = value;} void setN1Max(double value) {n1MaxValue = value;}
void setN2Min(double value) {n1MinValue = value;} void setN2Min(double value) {n1MinValue = value;}
void setN2Max(double value) {n2MaxValue = value;} void setN2Max(double value) {n2MaxValue = value;}
// Sets up needle/UAVObject connections:
void connectNeedles(QString object1, QString field1,
QString object2, QString field2);
protected: protected:
void paintEvent(QPaintEvent *event); void paintEvent(QPaintEvent *event);
@ -72,11 +75,17 @@ private:
QGraphicsSvgItem *m_foreground; QGraphicsSvgItem *m_foreground;
QGraphicsSvgItem *m_needle1; QGraphicsSvgItem *m_needle1;
QGraphicsSvgItem *m_needle2; QGraphicsSvgItem *m_needle2;
bool n2enabled; // Simple flag to skip rendering if the
bool fgenabled; // layer does not exist.
double n1MinValue; double n1MinValue;
double n1MaxValue; double n1MaxValue;
double n2MinValue; double n2MinValue;
double n2MaxValue; double n2MaxValue;
// The Value and target variables
// are expressed in degrees
double needle1Target; double needle1Target;
double needle1Value; double needle1Value;
double needle2Target; double needle2Target;