1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-21 11:54:15 +01:00

OP-102: fix for the compass 'jump': rotation now takes the shorter path, no jump anymore - testers welcome.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1146 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
edouard 2010-07-20 12:50:47 +00:00 committed by edouard
parent bcbd89167a
commit 6ef51b0c4d

View File

@ -33,14 +33,12 @@
PFDGadgetWidget::PFDGadgetWidget(QWidget *parent) : QGraphicsView(parent) PFDGadgetWidget::PFDGadgetWidget(QWidget *parent) : QGraphicsView(parent)
{ {
// TODO: create a proper "needle" object instead of hardcoding all this
// which is ugly (but easy).
setMinimumSize(64,64); setMinimumSize(64,64);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setScene(new QGraphicsScene(this)); setScene(new QGraphicsScene(this));
//setRenderHints(QPainter::Antialiasing || QPainter::TextAntialiasing); //setRenderHints(QPainter::Antialiasing || QPainter::TextAntialiasing);
setRenderHints(QPainter::TextAntialiasing); //setRenderHints(QPainter::TextAntialiasing);
m_renderer = new QSvgRenderer(); m_renderer = new QSvgRenderer();
@ -60,7 +58,6 @@ PFDGadgetWidget::PFDGadgetWidget(QWidget *parent) : QGraphicsView(parent)
altitudeTarget = 0; altitudeTarget = 0;
altitudeValue = 0; altitudeValue = 0;
// This timer mechanism makes needles rotate smoothly // This timer mechanism makes needles rotate smoothly
connect(&dialTimer, SIGNAL(timeout()), this, SLOT(moveNeedles())); connect(&dialTimer, SIGNAL(timeout()), this, SLOT(moveNeedles()));
dialTimer.start(20); dialTimer.start(20);
@ -134,6 +131,8 @@ void PFDGadgetWidget::connectNeedles() {
\brief Updates the link stats \brief Updates the link stats
*/ */
void PFDGadgetWidget::updateLinkStatus(UAVObject *object1) { void PFDGadgetWidget::updateLinkStatus(UAVObject *object1) {
// TODO: find a way to avoid updating the graphics if the value
// has not changed since the last update
// Double check that the field exists: // Double check that the field exists:
QString st = QString("Status"); QString st = QString("Status");
QString tdr = QString("TxDataRate"); QString tdr = QString("TxDataRate");
@ -199,7 +198,17 @@ void PFDGadgetWidget::updateHeading(UAVObject *object1) {
// These factors assume some things about the PFD SVG, namely: // These factors assume some things about the PFD SVG, namely:
// - Heading value in degrees // - Heading value in degrees
// - Scale is 540 degrees large // - Scale is 540 degrees large
headingTarget = field->getDouble()*compassBandWidth/(-540);
// Corvus Corax: "If you want a smooth transition between two angles, It is usually solved that by substracting
// one from another, and if the result is >180 or <-180 I substract (respectively add) 360 degrees
// to it. That way you always get the "shorter difference" to turn in."
double fac = compassBandWidth/540;
headingTarget = field->getDouble()*(-fac);
if ((headingValue - headingTarget)/fac > 180) {
headingTarget += 360*fac;
} else if (((headingValue - headingTarget)/fac < -180)) {
headingTarget -= 360*fac;
}
} else { } else {
qDebug() << "UpdateHeading: Wrong field, maybe an issue with object disconnection ?"; qDebug() << "UpdateHeading: Wrong field, maybe an issue with object disconnection ?";
} }
@ -239,12 +248,15 @@ void PFDGadgetWidget::updateHeading(UAVObject *object1) {
\brief Called by the UAVObject which got updated \brief Called by the UAVObject which got updated
*/ */
void PFDGadgetWidget::updateAirspeed(UAVObject *object3) { void PFDGadgetWidget::updateAirspeed(UAVObject *object3) {
Q_UNUSED(object3);
} }
/*! /*!
\brief Called by the UAVObject which got updated \brief Called by the UAVObject which got updated
*/ */
void PFDGadgetWidget::updateAltitude(UAVObject *object3) { void PFDGadgetWidget::updateAltitude(UAVObject *object3) {
Q_UNUSED(object3);
} }
@ -252,6 +264,8 @@ void PFDGadgetWidget::updateAltitude(UAVObject *object3) {
\brief Called by the UAVObject which got updated \brief Called by the UAVObject which got updated
*/ */
void PFDGadgetWidget::updateBattery(UAVObject *object1) { void PFDGadgetWidget::updateBattery(UAVObject *object1) {
// TODO: find a way to avoid updating the graphics if the value
// has not changed since the last update
// Double check that the field exists: // Double check that the field exists:
QString voltage = QString("Voltage"); QString voltage = QString("Voltage");
QString current = QString("Current"); QString current = QString("Current");
@ -702,6 +716,7 @@ void PFDGadgetWidget::paint()
void PFDGadgetWidget::paintEvent(QPaintEvent *event) void PFDGadgetWidget::paintEvent(QPaintEvent *event)
{ {
Q_UNUSED(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()) {
qDebug() << "Dial file not loaded, not rendering"; qDebug() << "Dial file not loaded, not rendering";
@ -715,6 +730,7 @@ void PFDGadgetWidget::paintEvent(QPaintEvent *event)
// nature of SVG dials. // nature of SVG dials.
void PFDGadgetWidget::resizeEvent(QResizeEvent *event) void PFDGadgetWidget::resizeEvent(QResizeEvent *event)
{ {
Q_UNUSED(event);
fitInView(m_background, Qt::KeepAspectRatio ); fitInView(m_background, Qt::KeepAspectRatio );
} }
@ -745,6 +761,7 @@ void PFDGadgetWidget::moveNeedles()
////// //////
// Roll // Roll
////// //////
if (rollValue != rollTarget) {
double rollDiff; double rollDiff;
if ((abs((rollValue-rollTarget)*10) > 5)) { if ((abs((rollValue-rollTarget)*10) > 5)) {
rollDiff =(rollTarget - rollValue)/5; rollDiff =(rollTarget - rollValue)/5;
@ -755,10 +772,14 @@ void PFDGadgetWidget::moveNeedles()
m_world->setRotation(m_world->rotation()+rollDiff); m_world->setRotation(m_world->rotation()+rollDiff);
m_rollscale->setRotation(m_rollscale->rotation()+rollDiff); m_rollscale->setRotation(m_rollscale->rotation()+rollDiff);
rollValue += rollDiff; rollValue += rollDiff;
} else {
dialCount--;
}
////// //////
// Pitch // Pitch
////// //////
if (pitchValue != pitchTarget) {
double pitchDiff; double pitchDiff;
if ((abs((pitchValue-pitchTarget)*10) > 5)) { if ((abs((pitchValue-pitchTarget)*10) > 5)) {
pitchDiff = (pitchTarget - pitchValue)/5; pitchDiff = (pitchTarget - pitchValue)/5;
@ -771,10 +792,18 @@ void PFDGadgetWidget::moveNeedles()
QPointF oop = m_world->transformOriginPoint(); QPointF oop = m_world->transformOriginPoint();
m_world->setTransformOriginPoint((oop.x()-opd.x()),(oop.y()-opd.y())); m_world->setTransformOriginPoint((oop.x()-opd.x()),(oop.y()-opd.y()));
pitchValue += pitchDiff; pitchValue += pitchDiff;
} else {
dialCount--;
}
////// //////
// Heading // Heading
//
// If you want a smooth transition between two angles, It is usually solved that by substracting
// one from another, and if the result is >180 or <-180 I substract (respectively add) 360 degrees
// to it. That way you always get the "shorter difference" to turn in.
////// //////
if (headingValue != headingTarget) {
double headingOffset = 0; double headingOffset = 0;
double headingDiff; double headingDiff;
if ((abs((headingValue-headingTarget)*10) > 5)) { if ((abs((headingValue-headingTarget)*10) > 5)) {
@ -787,19 +816,23 @@ void PFDGadgetWidget::moveNeedles()
// Note: rendering can jump oh so very slightly when crossing the 180 degree // Note: rendering can jump oh so very slightly when crossing the 180 degree
// boundary, should not impact actual useability of the display. // boundary, should not impact actual useability of the display.
if ((headingValue < threshold) && ((headingValue+headingDiff)>=threshold)) { if ((headingValue < threshold) && ((headingValue+headingDiff)>=threshold)) {
// We went over 180<38>: activate a -360 degree offset // We went over 180°: activate a -360 degree offset
headingOffset = 2*threshold; headingOffset = 2*threshold;
} else if ((headingValue >= threshold) && ((headingValue+headingDiff)<threshold)) { } else if ((headingValue >= threshold) && ((headingValue+headingDiff)<threshold)) {
// We went under 180<38>: remove the -360 degree offset // We went under 180°: remove the -360 degree offset
headingOffset = -2*threshold; headingOffset = -2*threshold;
} }
opd = QPointF(headingDiff+headingOffset,0); QPointF opd = QPointF(headingDiff+headingOffset,0);
m_compassband->setTransform(QTransform::fromTranslate(opd.x(),opd.y()), true); m_compassband->setTransform(QTransform::fromTranslate(opd.x(),opd.y()), true);
headingValue += headingDiff; headingValue += headingDiff;
} else {
dialCount--;
}
////// //////
// Speed // Speed
////// //////
if (groundspeedValue != groundspeedTarget) {
if (abs(groundspeedValue-groundspeedTarget) > speedScaleHeight/120) { if (abs(groundspeedValue-groundspeedTarget) > speedScaleHeight/120) {
groundspeedValue += (groundspeedTarget-groundspeedValue)/5; groundspeedValue += (groundspeedTarget-groundspeedValue)/5;
} else { } else {
@ -809,7 +842,7 @@ void PFDGadgetWidget::moveNeedles()
qreal x = m_speedscale->transform().dx(); qreal x = m_speedscale->transform().dx();
//opd = QPointF(x,fmod(groundspeedValue,speedScaleHeight/6)); //opd = QPointF(x,fmod(groundspeedValue,speedScaleHeight/6));
// fmod does rounding errors!! the formula below works better: // fmod does rounding errors!! the formula below works better:
opd = QPointF(x,groundspeedValue-floor(groundspeedValue/speedScaleHeight*6)*speedScaleHeight/6); QPointF opd = QPointF(x,groundspeedValue-floor(groundspeedValue/speedScaleHeight*6)*speedScaleHeight/6);
m_speedscale->setTransform(QTransform::fromTranslate(opd.x(),opd.y()), false); m_speedscale->setTransform(QTransform::fromTranslate(opd.x(),opd.y()), false);
double speedText = groundspeedValue/speedScaleHeight*30; double speedText = groundspeedValue/speedScaleHeight*30;
@ -829,31 +862,35 @@ void PFDGadgetWidget::moveNeedles()
val -= 5; val -= 5;
} }
} }
} else {
dialCount--;
}
////// //////
// Altitude // Altitude
////// //////
if (altitudeValue != altitudeTarget) {
if (abs(altitudeValue-altitudeTarget) > altitudeScaleHeight/120) { if (abs(altitudeValue-altitudeTarget) > altitudeScaleHeight/120) {
altitudeValue += (altitudeTarget-altitudeValue)/5; altitudeValue += (altitudeTarget-altitudeValue)/5;
} else { } else {
altitudeValue = altitudeTarget; altitudeValue = altitudeTarget;
dialCount--; dialCount--;
} }
x = m_altitudescale->transform().dx(); qreal x = m_altitudescale->transform().dx();
//opd = QPointF(x,fmod(altitudeValue,altitudeScaleHeight/6)); //opd = QPointF(x,fmod(altitudeValue,altitudeScaleHeight/6));
// fmod does rounding errors!! the formula below works better: // fmod does rounding errors!! the formula below works better:
opd = QPointF(x,altitudeValue-floor(altitudeValue/altitudeScaleHeight*6)*altitudeScaleHeight/6); QPointF opd = QPointF(x,altitudeValue-floor(altitudeValue/altitudeScaleHeight*6)*altitudeScaleHeight/6);
m_altitudescale->setTransform(QTransform::fromTranslate(opd.x(),opd.y()), false); m_altitudescale->setTransform(QTransform::fromTranslate(opd.x(),opd.y()), false);
double altitudeText = altitudeValue/altitudeScaleHeight*30; double altitudeText = altitudeValue/altitudeScaleHeight*30;
s = QString().sprintf("%.0f",altitudeText); QString s = QString().sprintf("%.0f",altitudeText);
m_altitudetext->setPlainText(s); m_altitudetext->setPlainText(s);
// TODO: optimize this by skipping if not necessary... // TODO: optimize this by skipping if not necessary...
// Now update the text elements inside the scale: // Now update the text elements inside the scale:
// (Qt documentation states that the list has the same order // (Qt documentation states that the list has the same order
// as the item add order in the QGraphicsItemGroup) // as the item add order in the QGraphicsItemGroup)
textList = m_altitudescale->childItems(); QList <QGraphicsItem *> textList = m_altitudescale->childItems();
val = 5*floor(altitudeValue/altitudeScaleHeight*6)+20; qreal val = 5*floor(altitudeValue/altitudeScaleHeight*6)+20;
foreach( QGraphicsItem * item, textList) { foreach( QGraphicsItem * item, textList) {
if (QGraphicsTextItem *text = qgraphicsitem_cast<QGraphicsTextItem *>(item)) { if (QGraphicsTextItem *text = qgraphicsitem_cast<QGraphicsTextItem *>(item)) {
QString s = (val<0) ? QString() : QString().sprintf("%.0f",val); QString s = (val<0) ? QString() : QString().sprintf("%.0f",val);
@ -861,8 +898,10 @@ void PFDGadgetWidget::moveNeedles()
val -= 5; val -= 5;
} }
} }
} else {
dialCount--;
}
//update();
if (!dialCount) if (!dialCount)
dialTimer.stop(); dialTimer.stop();
} }