1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

OP-82: Implemented Altimeter on the PFD, some speed/cpu optimizations as well.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@981 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
edouard 2010-07-01 22:28:19 +00:00 committed by edouard
parent a9695fc59e
commit 870b58efd4
3 changed files with 163 additions and 141 deletions

View File

@ -15,7 +15,7 @@
id="svg2"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="PFD-4.svg"
sodipodi:docname="PFD-2.svg"
style="display:inline"
inkscape:export-filename="H:\Documents\Hobbies\OpenPilot\SVN\artwork\PFD-2.png"
inkscape:export-xdpi="269.53"
@ -155,6 +155,20 @@
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3900"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3924"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
id="base"
@ -164,13 +178,13 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="489.14989"
inkscape:cy="349.86458"
inkscape:cx="501.01579"
inkscape:cy="324.15029"
inkscape:document-units="px"
inkscape:current-layer="layer5"
inkscape:current-layer="foreground"
showgrid="false"
inkscape:window-width="1280"
inkscape:window-height="998"
inkscape:window-height="744"
inkscape:window-x="-4"
inkscape:window-y="-4"
inkscape:window-maximized="1"
@ -448,11 +462,6 @@
inkscape:label="Foreground"
style="display:inline"
transform="translate(230.4171,-2.5493479)">
<path
style="fill:#000000;fill-opacity:0.49350652;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
d="m -18.1875,595.5 0,96.40625 88.90625,0 0.505076,0.007 430.628854,0 0.17857,0 88.6875,0 0,-96.41368 -65.125,0 -23.78125,23.78125 0.23331,-0.70982 -432.045806,0 0,0 L 46.9375,595.5 l -65.125,0 z"
id="path6922"
sodipodi:nodetypes="ccccccccccccccc" />
<g
id="foreground"
inkscape:label="#g3392">
@ -486,7 +495,7 @@
d="m 279.13165,125.4054 20.29336,-0.0329 -10.36931,-19.46879 -9.92405,19.50168 z"
id="path3779" />
<g
transform="translate(-9.5413867,-9.5367432e-7)"
transform="translate(16.458613,-9.5367432e-7)"
style="display:inline"
id="speed-bg"
inkscape:label="#g3820">
@ -508,7 +517,7 @@
inkscape:label="#g3820"
id="altitude-bg"
style="display:inline"
transform="matrix(-1,0,0,1,548.96105,-9.5367432e-7)">
transform="matrix(-1,0,0,1,562.96105,-9.5367432e-7)">
<rect
style="fill:#ffffff;fill-opacity:0.36363639;stroke:none;display:inline"
id="rect5640"
@ -520,9 +529,22 @@
inkscape:label="#rect6927"
style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
d="m -162.85715,337.78541 78.912165,0 0,9.3094 10.606602,9.3094 -10.606602,9.3094 0.08512,9.3094 -78.997285,0 0,-37.2376 z"
id="path5642"
id="altitude-window"
sodipodi:nodetypes="cccccccc" />
</g>
<rect
style="opacity:0.5;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.42740273;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
id="vario-bg"
width="41.465546"
height="339.4606"
x="727.99298"
y="186.60066"
inkscape:label="#rect5038" />
<path
style="fill:#000000;fill-opacity:0.49350652;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
d="m -15.423661,592.19188 0,96.40626 88.90625,0 0.50508,0.007 430.628851,0 0.17857,0 88.6875,0 0,-96.41369 -65.125,0 -23.78125,23.78125 0.23331,-0.70982 -432.045811,0 0,0 -23.0625,-23.071 -65.125,0 z"
id="path6922"
sodipodi:nodetypes="ccccccccccccccc" />
</g>
<g
id="g4301">
@ -2172,13 +2194,6 @@
id="tspan6949"
x="-91.428574"
y="355.71429" /></text>
<rect
style="opacity:0.5;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.42740273;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect5038"
width="41.465546"
height="339.4606"
x="712.56403"
y="190.85336" />
<g
id="speed-scale"
inkscape:label="#g4182"
@ -2312,94 +2327,6 @@
id="path4119" />
</g>
</g>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-153.55997"
y="364.96973"
id="text4227"><tspan
sodipodi:role="line"
id="tspan4229"
x="-153.55997"
y="364.96973"
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">999</tspan></text>
<text
id="text4267"
y="306.96973"
x="-153.55997"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial"
y="306.96973"
x="-153.55997"
id="tspan4269"
sodipodi:role="line">9999</tspan></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-153.55997"
y="234.96973"
id="text4271"><tspan
sodipodi:role="line"
id="tspan4273"
x="-153.55997"
y="234.96973"
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">9999</tspan></text>
<text
id="text4275"
y="164.96973"
x="-153.55997"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial"
y="164.96973"
x="-153.55997"
id="tspan4277"
sodipodi:role="line">9999</tspan></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-153.55997"
y="88.969727"
id="text4279"><tspan
sodipodi:role="line"
id="tspan4281"
x="-153.55997"
y="88.969727"
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">9999</tspan></text>
<text
id="text4283"
y="452.96973"
x="-153.55997"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial"
y="452.96973"
x="-153.55997"
id="tspan4285"
sodipodi:role="line">9999</tspan></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="-153.55997"
y="524.96973"
id="text4287"><tspan
sodipodi:role="line"
id="tspan4289"
x="-153.55997"
y="524.96973"
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial">9999</tspan></text>
<text
id="text4291"
y="596.96973"
x="-153.55997"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#ffffff;fill-opacity:1;font-family:Arial;-inkscape-font-specification:Arial"
y="596.96973"
x="-153.55997"
id="tspan4293"
sodipodi:role="line">9999</tspan></text>
<g
transform="matrix(-1,0,0,1,-318.58209,10.101525)"
inkscape:label="#g4182"

Before

Width:  |  Height:  |  Size: 255 KiB

After

Width:  |  Height:  |  Size: 251 KiB

View File

@ -128,8 +128,8 @@ void PFDGadgetWidget::updateAttitude(UAVObject *object1) {
*/
void PFDGadgetWidget::updateHeading(UAVObject *object1) {
// Double check that the field exists:
QString heading = QString("Heading");
UAVObjectField* field = object1->getField(heading);
QString fieldname = QString("Heading");
UAVObjectField* field = object1->getField(fieldname);
if (field) {
// These factors assume some things about the PFD SVG, namely:
// - Heading value in degrees
@ -138,13 +138,20 @@ void PFDGadgetWidget::updateHeading(UAVObject *object1) {
} else {
std::cout << "UpdateHeading: Wrong field, maybe an issue with object disconnection ?" << std::endl;
}
heading = QString("Groundspeed");
field = object1->getField(heading);
fieldname = QString("Groundspeed");
field = object1->getField(fieldname);
if (field) {
// The speed scale represents 30km/h (6 * 5)
// 3.6 : convert m/s to km/h
groundspeedTarget = 3.6*field->getDouble()*speedScaleHeight/(-30);
groundspeedTarget = 3.6*field->getDouble()*speedScaleHeight/(30);
}
fieldname = QString("Altitude");
field = object1->getField(fieldname);
if (field) {
// The altitude scale represents 30 meters
altitudeTarget = field->getDouble()*altitudeScaleHeight/(30);
}
if (!dialTimer.isActive())
dialTimer.start(); // Rearm the dial Timer which might be stopped.
@ -196,6 +203,9 @@ void PFDGadgetWidget::setDialFile(QString dfn)
- Speed rectangle (left side): speed-bg
- Speed scale: speed-scale.
- Black speed window: speed-window.
- Altitude rectangle (right site): altitude-bg.
- Altitude scale: altitude-scale.
- Black altitude window: altitude-window.
*/
QGraphicsScene *l_scene = scene();
l_scene->clear(); // Deletes all items contained in the scene as well.
@ -234,7 +244,9 @@ void PFDGadgetWidget::setDialFile(QString dfn)
m_foreground->setElementId("foreground");
l_scene->addItem(m_foreground);
// Compass:
////////////////////
// Compass
////////////////////
// Get the default location of the Compass:
QMatrix compassMatrix = m_renderer->matrixForElement("compass");
qreal startX = compassMatrix.mapRect(m_renderer->boundsOnElement("compass")).x();
@ -268,24 +280,27 @@ void PFDGadgetWidget::setDialFile(QString dfn)
// includes half the width of the letters, which causes errors:
compassBandWidth = m_renderer->boundsOnElement("compass-scale").width();
////////////////////
// Speed
////////////////////
// Speedometer on the left hand:
compassMatrix = m_renderer->matrixForElement("speed-bg");
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-bg")).x();
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-bg")).y();
m_speedbg = new QGraphicsSvgItem();
m_speedbg->setSharedRenderer(m_renderer);
m_speedbg->setElementId("speed-bg");
m_speedbg->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
QGraphicsSvgItem *verticalbg = new QGraphicsSvgItem();
verticalbg->setSharedRenderer(m_renderer);
verticalbg->setElementId("speed-bg");
verticalbg->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
QGraphicsItem::ItemClipsToShape);
l_scene->addItem(m_speedbg);
l_scene->addItem(verticalbg);
matrix.reset();
matrix.translate(startX,startY);
m_speedbg->setTransform(matrix,false);
verticalbg->setTransform(matrix,false);
// Note: speed-scale should contain exactly 6 major ticks
// for 30km/h
m_speedscale = new QGraphicsItemGroup();
m_speedscale->setParentItem(m_speedbg);
m_speedscale->setParentItem(verticalbg);
QGraphicsSvgItem *speedscalelines = new QGraphicsSvgItem();
speedscalelines->setSharedRenderer(m_renderer);
@ -295,12 +310,12 @@ void PFDGadgetWidget::setDialFile(QString dfn)
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-bg")).width();
startX -= m_renderer->matrixForElement("speed-scale").mapRect(
m_renderer->boundsOnElement("speed-scale")).width();
//speedscalelines->setParentItem(m_speedbg);
//speedscalelines->setParentItem(verticalbg);
matrix.reset();
matrix.translate(startX,0);
speedscalelines->setTransform(matrix,false);
// Quick way to reposition the item before putting it in the group:
speedscalelines->setParentItem(m_speedbg);
speedscalelines->setParentItem(verticalbg);
m_speedscale->addToGroup(speedscalelines); // (reparents the item)
// Add the scale text elements:
@ -310,7 +325,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
matrix.reset();
matrix.translate(compassMatrix.mapRect(m_renderer->boundsOnElement("speed-bg")).width()/10,-speedScaleHeight/30);
speed0->setTransform(matrix,false);
speed0->setParentItem(m_speedbg);
speed0->setParentItem(verticalbg);
m_speedscale->addToGroup(speed0);
for (int i=0; i<6;i++) {
speed0 = new QGraphicsTextItem("");
@ -319,13 +334,69 @@ void PFDGadgetWidget::setDialFile(QString dfn)
speed0->setPlainText(QString().setNum(i*5+1));
matrix.translate(0,speedScaleHeight/6);
speed0->setTransform(matrix,false);
speed0->setParentItem(m_speedbg);
speed0->setParentItem(verticalbg);
m_speedscale->addToGroup(speed0);
}
// Now vertically center the speed scale on the speed background
QRectF rectB = m_speedbg->boundingRect();
QRectF rectB = verticalbg->boundingRect();
QRectF rectN = speedscalelines->boundingRect();
m_speedscale->setPos(0,rectB.height()/2-rectN.height()/2);
m_speedscale->setPos(0,rectB.height()/2-rectN.height()/2-rectN.height()/6);
////////////////////
// Altitude
////////////////////
// Right hand, very similar to speed
compassMatrix = m_renderer->matrixForElement("altitude-bg");
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-bg")).x();
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-bg")).y();
verticalbg = new QGraphicsSvgItem();
verticalbg->setSharedRenderer(m_renderer);
verticalbg->setElementId("altitude-bg");
verticalbg->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
QGraphicsItem::ItemClipsToShape);
l_scene->addItem(verticalbg);
matrix.reset();
matrix.translate(startX,startY);
verticalbg->setTransform(matrix,false);
// Note: altitude-scale should contain exactly 6 major ticks
// for 30 meters
m_altitudescale = new QGraphicsItemGroup();
m_altitudescale->setParentItem(verticalbg);
QGraphicsSvgItem *altitudescalelines = new QGraphicsSvgItem();
altitudescalelines->setSharedRenderer(m_renderer);
altitudescalelines->setElementId("altitude-scale");
altitudeScaleHeight = m_renderer->matrixForElement("altitude-scale").mapRect(
m_renderer->boundsOnElement("altitude-scale")).height();
// Quick way to reposition the item before putting it in the group:
altitudescalelines->setParentItem(verticalbg);
m_altitudescale->addToGroup(altitudescalelines); // (reparents the item)
// Add the scale text elements:
speed0 = new QGraphicsTextItem("XXXX");
speed0->setDefaultTextColor(QColor("White"));
speed0->setFont(QFont("Arial",(int) altitudeScaleHeight/30));
matrix.reset();
matrix.translate(m_renderer->matrixForElement("altitude-scale").mapRect(m_renderer->boundsOnElement("altitude-scale")).width()
+ m_renderer->matrixForElement("altitude-bg").mapRect(m_renderer->boundsOnElement("altitude-bg")).width()/10,-altitudeScaleHeight/30);
speed0->setTransform(matrix,false);
speed0->setParentItem(verticalbg);
m_altitudescale->addToGroup(speed0);
for (int i=0; i<6;i++) {
speed0 = new QGraphicsTextItem("XXXX");
speed0->setDefaultTextColor(QColor("White"));
speed0->setFont(QFont("Arial",(int) altitudeScaleHeight/30));
speed0->setPlainText(QString().setNum(i*5+1));
matrix.translate(0,altitudeScaleHeight/6);
speed0->setTransform(matrix,false);
speed0->setParentItem(verticalbg);
m_altitudescale->addToGroup(speed0);
}
// Now vertically center the speed scale on the speed background
rectB = verticalbg->boundingRect();
rectN = altitudescalelines->boundingRect();
m_altitudescale->setPos(0,rectB.height()/2-rectN.height()/2-rectN.height()/6);
l_scene->setSceneRect(m_background->boundingRect());
@ -357,6 +428,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
pitchValue = 0;
headingValue = 0;
groundspeedValue = 0;
altitudeValue = 0;
if (!dialTimer.isActive())
dialTimer.start(); // Rearm the dial Timer which might be stopped.
}
@ -402,7 +474,7 @@ void PFDGadgetWidget::moveVerticalScales() {
//
void PFDGadgetWidget::moveNeedles()
{
int dialCount = 4; // Gets decreased by one for each element
int dialCount = 5; // Gets decreased by one for each element
// which has finished moving
/// TODO: optimize!!!
@ -464,31 +536,57 @@ void PFDGadgetWidget::moveNeedles()
//////
// Speed
//
// TODO: find a way to move the speed scale faster if we are far
// from the target, maybe a separate timer would be useful there?
// What is the consequence on CPU usage?
//////
if ((abs((groundspeedValue-groundspeedTarget)*10) > 5)) {
if (abs(groundspeedValue-groundspeedTarget) > speedScaleHeight/120) {
groundspeedValue += (groundspeedTarget-groundspeedValue)/5;
} else {
groundspeedValue = groundspeedTarget;
dialCount--;
}
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:
opd = QPointF(x,groundspeedValue-floor(groundspeedValue/speedScaleHeight*6)*speedScaleHeight/6);
m_speedscale->setTransform(QTransform::fromTranslate(opd.x(),opd.y()), false);
// TODO: optimize this by skipping if not necessary...
// Now update the text elements inside the scale:
// (Qt documentation states that the list has the same order
// as the item add order in the QGraphicsItemGroup)
QList <QGraphicsItem *> textList = m_speedscale->childItems();
qreal val = -5*ceil(groundspeedValue/speedScaleHeight*6)-15;
qreal val = 5*floor(groundspeedValue/speedScaleHeight*6)+20;
foreach( QGraphicsItem * item, textList) {
if (QGraphicsTextItem *text = qgraphicsitem_cast<QGraphicsTextItem *>(item)) {
QString s = (val<0) ? QString() : QString().sprintf("%.0f",val);
text->setPlainText(s);
val += 5;
val -= 5;
}
}
//////
// Altitude
//////
if (abs(altitudeValue-altitudeTarget) > altitudeScaleHeight/120) {
altitudeValue += (altitudeTarget-altitudeValue)/5;
} else {
altitudeValue = altitudeTarget;
dialCount--;
}
x = m_altitudescale->transform().dx();
//opd = QPointF(x,fmod(altitudeValue,altitudeScaleHeight/6));
// fmod does rounding errors!! the formula below works better:
opd = QPointF(x,altitudeValue-floor(altitudeValue/altitudeScaleHeight*6)*altitudeScaleHeight/6);
m_altitudescale->setTransform(QTransform::fromTranslate(opd.x(),opd.y()), false);
// TODO: optimize this by skipping if not necessary...
// Now update the text elements inside the scale:
// (Qt documentation states that the list has the same order
// as the item add order in the QGraphicsItemGroup)
textList = m_altitudescale->childItems();
val = 5*floor(altitudeValue/altitudeScaleHeight*6)+20;
foreach( QGraphicsItem * item, textList) {
if (QGraphicsTextItem *text = qgraphicsitem_cast<QGraphicsTextItem *>(item)) {
QString s = (val<0) ? QString() : QString().sprintf("%.0f",val);
text->setPlainText(s);
val -= 5;
}
}

View File

@ -96,14 +96,10 @@ private:
QGraphicsSvgItem *m_homepointbearing;
// Next point bearing:
QGraphicsSvgItem *m_nextpointbearing;
// Vertical speed frame:
QGraphicsSvgItem *m_speedbg;
// Vertical Speed scale:
QGraphicsItemGroup *m_speedscale;
// Vertical altitude frame:
QGraphicsSvgItem *m_altitudebg;
// Vertical altitude scale:
QGraphicsSvgItem *m_altitudescale;
QGraphicsItemGroup *m_altitudescale;
double n1MinValue;
double n1MaxValue;
@ -130,6 +126,7 @@ private:
qreal compassBandWidth;
qreal speedScaleHeight;
qreal altitudeScaleHeight;
// Name of the fields to read when an update is received:
UAVDataObject* attitudeObj;