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:
parent
bcbd89167a
commit
6ef51b0c4d
@ -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();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user