Newer
Older
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Implementation of Horizontal Situation Indicator class
*
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#include <QFile>
#include <QStringList>
#include <QGraphicsScene>
#include <QHBoxLayout>
#include <QDoubleSpinBox>
#include "UASManager.h"
#include "HSIDisplay.h"
#include "MG.h"
#include "UASWaypointManager.h"
#include "Waypoint2DIcon.h"
HSIDisplay::HSIDisplay(QWidget *parent) :
satellitesUsed(0),
attXSet(0),
attYSet(0),
attYawSet(0),
altitudeSet(1.0),
posXSet(0),
posYSet(0),
posZSet(0),
attXSaturation(0.5f),
attYSaturation(0.5f),
attYawSaturation(0.5f),
posXSaturation(0.05),
posYSaturation(0.05),
altitudeSaturation(1.0),
lat(0),
lon(0),
alt(0),
globalAvailable(0),
x(0),
y(0),
z(0),
vx(0),
vy(0),
vz(0),
speed(0),
localAvailable(0),
roll(0),
pitch(0),
bodyXSetCoordinate(0.0f),
bodyYSetCoordinate(0.0f),
bodyZSetCoordinate(0.0f),
bodyYawSet(0.0f),
uiXSetCoordinate(0.0f),
uiYSetCoordinate(0.0f),
uiZSetCoordinate(0.0f),
uiYawSet(0.0f),
positionLock(false),
attControlEnabled(false),
xyControlEnabled(false),
yawControlEnabled(false),
positionFix(0),
gpsFix(0),
visionFix(0),
laserFix(0),
mavInitialized(false),
bottomMargin(3.0f),
topMargin(3.0f)
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
// this->setScene(new QGraphicsScene(-metricWidth/2.0f, -metricWidth/2.0f, metricWidth, metricWidth, this));
yCenterPos = vheight/2.0f + topMargin - bottomMargin;
// Add interaction elements
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setMargin(2);
layout->setSpacing(0);
QDoubleSpinBox* spinBox = new QDoubleSpinBox(this);
spinBox->setMinimum(0.1);
spinBox->setMaximum(9999);
connect(spinBox, SIGNAL(valueChanged(double)), this, SLOT(setMetricWidth(double)));
connect(this, SIGNAL(metricWidthChanged(double)), spinBox, SLOT(setValue(double)));
layout->addWidget(spinBox);
layout->setAlignment(spinBox, Qt::AlignBottom | Qt::AlignLeft);
this->setLayout(layout);
Mariano Lizarraga
committed
this->setVisible(false);
// Do first update
setMetricWidth(metricWidth);
void HSIDisplay::paintEvent(QPaintEvent * event)
{
Q_UNUSED(event);
//paintGL();
static quint64 interval = 0;
//qDebug() << "INTERVAL:" << MG::TIME::getGroundTimeNow() - interval << __FILE__ << __LINE__;
renderOverlay();
void HSIDisplay::renderOverlay()
// Center location of the HSI gauge items
//const float margin = 0.1f; // 10% margin of total width on each side
float baseRadius = (vheight - topMargin - bottomMargin) / 2.0f - bottomMargin / 2.0f;
// Draw instruments
// TESTING THIS SHOULD BE MOVED INTO A QGRAPHICSVIEW
// Update scaling factor
// adjust scaling to fit both horizontally and vertically
scalingFactor = this->width()/vwidth;
double scalingFactorH = this->height()/vheight;
if (scalingFactorH < scalingFactor) scalingFactor = scalingFactorH;
QPainter painter(viewport());
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
//painter.fillRect(QRect(0, 0, width(), height()), backgroundColor);
// Draw base instrument
// ----------------------
const QColor ringColor = QColor(200, 250, 200);
QPen pen;
pen.setColor(ringColor);
pen.setWidth(refLineWidthToPen(0.1f));
painter.setPen(pen);
float radius = (vwidth - topMargin - bottomMargin) / (2.0f * i+1) / 2.0f - bottomMargin / 2.0f;
drawCircle(xCenterPos, yCenterPos, radius, 0.1f, ringColor, &painter);
// Draw orientation labels
// Translate and rotate coordinate frame
painter.translate((xCenterPos)*scalingFactor, (yCenterPos)*scalingFactor);
painter.rotate((yaw/(M_PI))*180.0f);
paintText(tr("N"), ringColor, 3.5f, - 1.0f, - baseRadius - 5.5f, &painter);
paintText(tr("S"), ringColor, 3.5f, - 1.0f, + baseRadius + 1.5f, &painter);
paintText(tr("E"), ringColor, 3.5f, + baseRadius + 2.0f, - 1.75f, &painter);
paintText(tr("W"), ringColor, 3.5f, - baseRadius - 5.5f, - 1.75f, &painter);
painter.rotate((-yaw/(M_PI))*180.0f);
painter.translate(-(xCenterPos)*scalingFactor, -(yCenterPos)*scalingFactor);
QPolygonF p(3);
p.replace(0, QPointF(xCenterPos, yCenterPos-2.8484f));
p.replace(1, QPointF(xCenterPos-2.0f, yCenterPos+2.0f));
p.replace(2, QPointF(xCenterPos+2.0f, yCenterPos+2.0f));
drawPolygon(p, &painter);
// Draw satellites
drawGPS(painter);
// Draw state indicator
// Draw position
drawPositionDirection(xCenterPos, yCenterPos, baseRadius, positionColor, &painter);
// Draw attitude
QColor attitudeColor(200, 20, 20);
drawAttitudeDirection(xCenterPos, yCenterPos, baseRadius, attitudeColor, &painter);
// Draw position setpoints in body coordinates
if (uiXSetCoordinate != 0 || uiYSetCoordinate != 0)
{
QColor spColor(150, 150, 150);
drawSetpointXY(uiXSetCoordinate, uiYSetCoordinate, uiYawSet, spColor, painter);
}
if (bodyXSetCoordinate != 0 || bodyYSetCoordinate != 0)
{
// Draw setpoint
drawSetpointXY(bodyXSetCoordinate, bodyYSetCoordinate, bodyYawSet, QGC::colorCyan, painter);
// Draw travel direction line
QPointF m(bodyXSetCoordinate, bodyYSetCoordinate);
// Transform from body to world coordinates
m = metricWorldToBody(m);
// Scale from metric body to screen reference units
drawLine(s.x(), s.y(), xCenterPos, yCenterPos, 1.5f, QGC::colorCyan, &painter);
}
// Labels on outer part and bottom
QString str;
str.sprintf("%05.2f %05.2f %05.2f m", x, y, z);
paintText(str, ringColor, 3.0f, xCenterPos + baseRadius - 30.75f, vheight - 5.0f, &painter);
// Speed
str.sprintf("%05.2f m/s", speed);
paintText(str, ringColor, 3.0f, 10.0f, vheight - 5.0f, &painter);
// Draw waypoints
drawWaypoints(painter);
// Draw status flags
drawStatusFlag(2, 1, tr("ATT"), attControlEnabled, painter);
drawStatusFlag(22, 1, tr("PXY"), xyControlEnabled, painter);
drawStatusFlag(44, 1, tr("PZ"), zControlEnabled, painter);
drawStatusFlag(66, 1, tr("YAW"), yawControlEnabled, painter);
// Draw position lock indicators
drawPositionLock(2, 5, tr("POS"), positionFix, painter);
drawPositionLock(22, 5, tr("VIS"), visionFix, painter);
drawPositionLock(44, 5, tr("GPS"), gpsFix, painter);
drawPositionLock(66, 5, tr("IRU"), iruFix, painter);
void HSIDisplay::drawStatusFlag(float x, float y, QString label, bool status, QPainter& painter)
{
paintText(label, QGC::colorCyan, 2.6f, x, y+0.35f, &painter);
QColor statusColor(250, 250, 250);
if(status)
{
painter.setBrush(QGC::colorDarkYellow);
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
}
painter.setPen(Qt::NoPen);
painter.drawRect(QRect(refToScreenX(x+7.3f), refToScreenY(y+0.05), refToScreenX(7.0f), refToScreenY(4.0f)));
paintText((status) ? tr("ON") : tr("OFF"), statusColor, 2.6f, x+7.9f, y+0.35f, &painter);
}
void HSIDisplay::drawPositionLock(float x, float y, QString label, int status, QPainter& painter)
{
paintText(label, QGC::colorCyan, 2.6f, x, y+0.35f, &painter);
QColor negStatusColor(200, 20, 20);
QColor posStatusColor(20, 200, 20);
QColor statusColor(250, 250, 250);
if(status > 0 && status < 4)
{
painter.setBrush(posStatusColor);
}
else
{
painter.setBrush(negStatusColor);
}
// Lock text
QString lockText;
switch (status)
{
case 1:
lockText = tr("LOC");
break;
case 2:
lockText = tr("2D");
break;
case 3:
lockText = tr("3D");
break;
default:
lockText = tr("NO");
break;
}
painter.setPen(Qt::NoPen);
painter.drawRect(QRect(refToScreenX(x+7.3f), refToScreenY(y+0.05), refToScreenX(7.0f), refToScreenY(4.0f)));
paintText(lockText, statusColor, 2.6f, x+7.9f, y+0.35f, &painter);
}
void HSIDisplay::updatePositionLock(UASInterface* uas, bool lock)
{
void HSIDisplay::updateAttitudeControllerEnabled(bool enabled)
void HSIDisplay::updatePositionXYControllerEnabled(bool enabled)
void HSIDisplay::updatePositionZControllerEnabled(bool enabled)
QPointF HSIDisplay::metricWorldToBody(QPointF world)
{
// First translate to body-centered coordinates
// Rotate around -yaw
float angle = yaw + M_PI;
QPointF result(cos(angle) * (x - world.x()) - sin(angle) * (y - world.y()), sin(angle) * (x - world.x()) + cos(angle) * (y - world.y()));
return result;
}
QPointF HSIDisplay::metricBodyToWorld(QPointF body)
{
// First rotate into world coordinates
// then translate to world position
QPointF result((cos(yaw) * body.x()) + (sin(yaw) * body.y()) + x, (-sin(yaw) * body.x()) + (cos(yaw) * body.y()) + y);
QPointF HSIDisplay::screenToMetricBody(QPointF ref)
{
return QPointF(-((screenToRefY(ref.y()) - yCenterPos)/ vwidth) * metricWidth - x, ((screenToRefX(ref.x()) - xCenterPos) / vwidth) * metricWidth - y);
}
QPointF HSIDisplay::refToMetricBody(QPointF &ref)
{
return QPointF(-((ref.y() - yCenterPos)/ vwidth) * metricWidth - x, ((ref.x() - xCenterPos) / vwidth) * metricWidth - y);
}
/**
* @see refToScreenX()
*/
QPointF HSIDisplay::metricBodyToRef(QPointF &metric)
{
return QPointF(((metric.y())/ metricWidth) * vwidth + xCenterPos, ((-metric.x()) / metricWidth) * vwidth + yCenterPos);
}
QPointF HSIDisplay::metricBodyToScreen(QPointF metric)
{
QPointF ref = metricBodyToRef(metric);
ref.setX(refToScreenX(ref.x()));
ref.setY(refToScreenY(ref.y()));
return ref;
}
void HSIDisplay::mouseDoubleClickEvent(QMouseEvent * event)
{
static bool dragStarted;
static float startX;
if (event->MouseButtonDblClick)
{
//setBodySetpointCoordinateXY(-refToMetric(screenToRefY(event->y()) - yCenterPos), refToMetric(screenToRefX(event->x()) - xCenterPos));
QPointF p = screenToMetricBody(event->posF());
setBodySetpointCoordinateXY(p.x(), p.y());
qDebug() << "Double click at x: " << screenToRefX(event->x()) - xCenterPos << "y:" << screenToRefY(event->y()) - yCenterPos;
}
else if (event->MouseButtonPress)
{
if (event->button() == Qt::RightButton)
{
// Start tracking mouse move
dragStarted = true;
}
else if (event->button() == Qt::LeftButton)
{
}
}
else if (event->MouseButtonRelease)
{
dragStarted = false;
}
if (dragStarted) uiYawSet += (startX - event->globalX()) / this->frameSize().width();
void HSIDisplay::setMetricWidth(double width)
{
if (width != metricWidth)
{
metricWidth = width;
emit metricWidthChanged(metricWidth);
}
}
/**
*
* @param uas the UAS/MAV to monitor/display with the HUD
*/
void HSIDisplay::setActiveUAS(UASInterface* uas)
{
if (this->uas != NULL && this->uas != uas)
{
// Disconnect any previously connected active MAV
//disconnect(uas, SIGNAL(valueChanged(UASInterface*,QString,double,quint64)), this, SLOT(updateValue(UASInterface*,QString,double,quint64)));
}
HDDisplay::setActiveUAS(uas);
//qDebug() << "ATTEMPTING TO SET UAS";
connect(uas, SIGNAL(gpsSatelliteStatusChanged(int,int,float,float,float,bool)), this, SLOT(updateSatellite(int,int,float,float,float,bool)));
connect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateLocalPosition(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(attitudeThrustSetPointChanged(UASInterface*,double,double,double,double,quint64)), this, SLOT(updateAttitudeSetpoints(UASInterface*,double,double,double,double,quint64)));
connect(uas, SIGNAL(positionSetPointsChanged(int,float,float,float,float,quint64)), this, SLOT(updatePositionSetpoints(int,float,float,float,float,quint64)));
connect(uas, SIGNAL(speedChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateSpeed(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(attitudeControlEnabled(bool)), this, SLOT(updateAttitudeControllerEnabled(bool)));
connect(uas, SIGNAL(positionXYControlEnabled(bool)), this, SLOT(updatePositionXYControllerEnabled(bool)));
connect(uas, SIGNAL(positionZControlEnabled(bool)), this, SLOT(updatePositionZControllerEnabled(bool)));
connect(uas, SIGNAL(positionYawControlEnabled(bool)), this, SLOT(updatePositionYawControllerEnabled(bool)));
connect(uas, SIGNAL(localizationChanged(UASInterface*,int)), this, SLOT(updateLocalization(UASInterface*,int)));
connect(uas, SIGNAL(visionLocalizationChanged(UASInterface*,int)), this, SLOT(updateVisionLocalization(UASInterface*,int)));
connect(uas, SIGNAL(gpsLocalizationChanged(UASInterface*,int)), this, SLOT(updateGpsLocalization(UASInterface*,int)));
connect(uas, SIGNAL(irUltraSoundLocalizationChanged(UASInterface*,int)), this, SLOT(updateInfraredUltrasoundLocalization(UASInterface*,int)));
// Now connect the new UAS
//if (this->uas != uas)
// {
//qDebug() << "UAS SET!" << "ID:" << uas->getUASID();
// Setup communication
//connect(uas, SIGNAL(valueChanged(UASInterface*,QString,double,quint64)), this, SLOT(updateValue(UASInterface*,QString,double,quint64)));
//}
}
void HSIDisplay::updateSpeed(UASInterface* uas, double vx, double vy, double vz, quint64 time)
{
Q_UNUSED(uas);
Q_UNUSED(time);
this->vx = vx;
this->vy = vy;
this->vz = vz;
this->speed = sqrt(pow(vx, 2.0f) + pow(vy, 2.0f) + pow(vz, 2.0f));
}
void HSIDisplay::setBodySetpointCoordinateXY(double x, double y)
{
// Set coordinates and send them out to MAV
QPointF sp(x, y);
sp = metricBodyToWorld(sp);
uiXSetCoordinate = sp.x();
uiYSetCoordinate = sp.y();
qDebug() << "Attempting to set new setpoint at x: " << x << "metric y:" << y;
if (uas && mavInitialized)
{
uas->setLocalPositionSetpoint(uiXSetCoordinate, uiYSetCoordinate, uiZSetCoordinate, uiYawSet);
qDebug() << "Setting new setpoint at x: " << x << "metric y:" << y;
}
}
void HSIDisplay::setBodySetpointCoordinateZ(double z)
{
// Set coordinates and send them out to MAV
uiZSetCoordinate = z;
}
void HSIDisplay::sendBodySetPointCoordinates()
{
// Send the coordinates to the MAV
}
void HSIDisplay::updateAttitudeSetpoints(UASInterface* uas, double rollDesired, double pitchDesired, double yawDesired, double thrustDesired, quint64 usec)
Q_UNUSED(uas);
Q_UNUSED(usec);
attXSet = pitchDesired;
attYSet = rollDesired;
attYawSet = yawDesired;
altitudeSet = thrustDesired;
void HSIDisplay::updateAttitude(UASInterface* uas, double roll, double pitch, double yaw, quint64 time)
{
Q_UNUSED(uas);
Q_UNUSED(time);
this->roll = roll;
this->pitch = pitch;
this->yaw = yaw;
}
void HSIDisplay::updatePositionSetpoints(int uasid, float xDesired, float yDesired, float zDesired, float yawDesired, quint64 usec)
bodyXSetCoordinate = xDesired;
bodyYSetCoordinate = yDesired;
bodyZSetCoordinate = zDesired;
bodyYawSet = yawDesired;
// qDebug() << "Received setpoint at x: " << x << "metric y:" << y;
// posXSet = xDesired;
// posYSet = yDesired;
// posZSet = zDesired;
// posYawSet = yawDesired;
}
void HSIDisplay::updateLocalPosition(UASInterface*, double x, double y, double z, quint64 usec)
{
this->x = x;
this->y = y;
this->z = z;
localAvailable = usec;
}
void HSIDisplay::updateGlobalPosition(UASInterface*, double lat, double lon, double alt, quint64 usec)
{
this->lat = lat;
this->lon = lon;
this->alt = alt;
globalAvailable = usec;
void HSIDisplay::updateSatellite(int uasid, int satid, float elevation, float azimuth, float snr, bool used)
gpsSatellites.value(satid)->update(satid, elevation, azimuth, snr, used);
gpsSatellites.insert(satid, new GPSSatellite(satid, elevation, azimuth, snr, used));
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
void HSIDisplay::updatePositionYawControllerEnabled(bool enabled)
{
yawControlEnabled = enabled;
}
/**
* @param fix 0: lost, 1: 2D local position hold, 2: 2D localization, 3: 3D localization
*/
void HSIDisplay::updateLocalization(UASInterface* uas, int fix)
{
Q_UNUSED(uas);
positionFix = fix;
}
/**
* @param fix 0: lost, 1: at least one satellite, but no GPS fix, 2: 2D localization, 3: 3D localization
*/
void HSIDisplay::updateGpsLocalization(UASInterface* uas, int fix)
{
Q_UNUSED(uas);
gpsFix = fix;
}
/**
* @param fix 0: lost, 1: 2D local position hold, 2: 2D localization, 3: 3D localization
*/
void HSIDisplay::updateVisionLocalization(UASInterface* uas, int fix)
{
Q_UNUSED(uas);
visionFix = fix;
}
/**
* @param fix 0: lost, 1-N: Localized with N ultrasound or infrared sensors
*/
void HSIDisplay::updateInfraredUltrasoundLocalization(UASInterface* uas, int fix)
{
Q_UNUSED(uas);
iruFix = fix;
}
if (snr > 0 && snr < 30)
{
color = QColor(250, 10, 10);
}
else if (snr >= 30 && snr < 35)
}
else
{
color = QColor(180, 180, 180);
}
return color;
void HSIDisplay::drawSetpointXY(float x, float y, float yaw, const QColor &color, QPainter &painter)
float radius = vwidth / 20.0f;
QPen pen(color);
pen.setWidthF(refLineWidthToPen(0.4f));
pen.setColor(color);
painter.setPen(pen);
painter.setBrush(Qt::NoBrush);
QPointF in(x, y);
// Transform from body to world coordinates
in = metricWorldToBody(in);
// Scale from metric to screen reference coordinates
drawCircle(p.x(), p.y(), radius, 0.4f, color, &painter);
radius *= 0.8;
drawLine(p.x(), p.y(), p.x()+sin(yaw) * radius, p.y()-cos(yaw) * radius, refLineWidthToPen(0.4f), color, &painter);
painter.setBrush(color);
drawCircle(p.x(), p.y(), radius * 0.1f, 0.1f, color, &painter);
}
void HSIDisplay::drawWaypoints(QPainter& painter)
{
const QVector<Waypoint*>& list = uas->getWaypointManager().getWaypointList();
// for (int i = 0; i < list.size(); i++)
// {
// QPointF in(list.at(i)->getX(), list.at(i)->getY());
// // Transform from world to body coordinates
// in = metricWorldToBody(in);
// // Scale from metric to screen reference coordinates
// QPointF p = metricBodyToRef(in);
// Waypoint2DIcon* wp = new Waypoint2DIcon();
// wp->setLocalPosition(list.at(i)->getX(), list.at(i)->getY());
// wp->setPos(0, 0);
// scene()->addItem(wp);
// }
QColor color;
painter.setBrush(Qt::NoBrush);
QPointF lastWaypoint;
for (int i = 0; i < list.size(); i++)
QPointF in(list.at(i)->getX(), list.at(i)->getY());
// Transform from world to body coordinates
in = metricWorldToBody(in);
// Scale from metric to screen reference coordinates
QPointF p = metricBodyToRef(in);
// Setup pen
QPen pen(color);
painter.setBrush(Qt::NoBrush);
// DRAW WAYPOINT
//drawCircle(p.x(), p.y(), radius, 0.4f, color, &painter);
float waypointSize = vwidth / 20.0f * 2.0f;
QPolygonF poly(4);
// Top point
poly.replace(0, QPointF(p.x(), p.y()-waypointSize/2.0f));
// Right point
poly.replace(1, QPointF(p.x()+waypointSize/2.0f, p.y()));
// Bottom point
poly.replace(2, QPointF(p.x(), p.y() + waypointSize/2.0f));
poly.replace(3, QPointF(p.x() - waypointSize/2.0f, p.y()));
// Select color based on if this is the current waypoint
if (list.at(i)->getCurrent())
{
color = QGC::colorCyan;//uas->getColor();
pen.setWidthF(refLineWidthToPen(0.8f));
}
else
{
color = uas->getColor();
pen.setWidthF(refLineWidthToPen(0.4f));
pen.setColor(color);
painter.setPen(pen);
float radius = (waypointSize/2.0f) * 0.8 * (1/sqrt(2.0f));
drawLine(p.x(), p.y(), p.x()+sin(list.at(i)->getYaw()+yaw) * radius, p.y()-cos(list.at(i)->getYaw()+yaw) * radius, refLineWidthToPen(0.4f), color, &painter);
drawPolygon(poly, &painter);
// DRAW CONNECTING LINE
// Draw line from last waypoint to this one
if (!lastWaypoint.isNull())
{
pen.setWidthF(refLineWidthToPen(0.4f));
painter.setPen(pen);
color = uas->getColor();
drawLine(lastWaypoint.x(), lastWaypoint.y(), p.x(), p.y(), refLineWidthToPen(0.4f), color, &painter);
}
lastWaypoint = p;
void HSIDisplay::drawSafetyArea(const QPointF &topLeft, const QPointF &bottomRight, const QColor &color, QPainter &painter)
{
QPen pen(color);
pen.setWidthF(refLineWidthToPen(0.1f));
pen.setColor(color);
painter.setPen(pen);
painter.drawRect(QRectF(metricBodyToScreen(metricWorldToBody(topLeft)), metricBodyToScreen(metricWorldToBody(bottomRight))));
void HSIDisplay::drawGPS(QPainter &painter)
{
float xCenter = xCenterPos;
float yCenter = xCenterPos;
const float margin = 0.15f; // 20% margin of total width on each side
float radius = (vwidth - vwidth * 2.0f * margin) / 2.0f;
quint64 currTime = MG::TIME::getGroundTimeNowUsecs();
// Draw satellite labels
// QString label;
// label.sprintf("%05.1f", value);
// paintText(label, color, 4.5f, xRef-7.5f, yRef-2.0f, painter);
QMapIterator<int, GPSSatellite*> i(gpsSatellites);
while (i.hasNext())
i.next();
GPSSatellite* sat = i.value();
// Check if update is not older than 5 seconds, else delete satellite
if (sat->lastUpdate + 1000000 < currTime)
{
// Delete and go to next satellite
gpsSatellites.remove(i.key());
if (i.hasNext())
{
i.next();
sat = i.value();
}
else
{
continue;
}
}
if (sat)
{
// Draw satellite
QBrush brush;
QColor color = getColorForSNR(sat->snr);
brush.setColor(color);
if (sat->used)
{
brush.setStyle(Qt::SolidPattern);
}
else
{
brush.setStyle(Qt::NoBrush);
}
painter.setPen(Qt::SolidLine);
painter.setPen(color);
painter.setBrush(brush);
float xPos = xCenter + (sin(((sat->azimuth/255.0f)*360.0f)/180.0f * M_PI) * cos(sat->elevation/180.0f * M_PI)) * radius;
float yPos = yCenter - (cos(((sat->azimuth/255.0f)*360.0f)/180.0f * M_PI) * cos(sat->elevation/180.0f * M_PI)) * radius;
// Draw circle for satellite, filled for used satellites
paintText(QString::number(sat->id), QColor(255, 255, 255), 2.9f, xPos+1.7f, yPos+2.0f, &painter);
void HSIDisplay::drawObjects(QPainter &painter)
void HSIDisplay::drawPositionDirection(float xRef, float yRef, float radius, const QColor& color, QPainter* painter)
// Draw the needle
const float maxWidth = radius / 10.0f;
const float minWidth = maxWidth * 0.3f;
float angle = atan2(posXSet, -posYSet);
angle -= M_PI/2.0f;
//radius *= ((posXSaturation + posYSaturation) - sqrt(pow(posXSet, 2), pow(posYSet, 2))) / (2*posXSaturation);
radius *= sqrt(pow(posXSet, 2) + pow(posYSet, 2)) / sqrt(posXSaturation + posYSaturation);
p.replace(0, QPointF(xRef-maxWidth/2.0f, yRef-radius * 0.4f));
p.replace(1, QPointF(xRef-minWidth/2.0f, yRef-radius * 0.9f));
p.replace(2, QPointF(xRef+minWidth/2.0f, yRef-radius * 0.9f));
p.replace(3, QPointF(xRef+maxWidth/2.0f, yRef-radius * 0.4f));
p.replace(4, QPointF(xRef, yRef-radius * 0.36f));
p.replace(5, QPointF(xRef-maxWidth/2.0f, yRef-radius * 0.4f));
rotatePolygonClockWiseRad(p, angle, QPointF(xRef, yRef));
QBrush indexBrush;
indexBrush.setColor(color);
indexBrush.setStyle(Qt::SolidPattern);
painter->setPen(Qt::SolidLine);
painter->setPen(color);
painter->setBrush(indexBrush);
drawPolygon(p, painter);
//qDebug() << "DRAWING POS SETPOINT X:" << posXSet << "Y:" << posYSet << angle;
void HSIDisplay::drawAttitudeDirection(float xRef, float yRef, float radius, const QColor& color, QPainter* painter)
// Draw the needle
const float maxWidth = radius / 10.0f;
const float minWidth = maxWidth * 0.3f;
float angle = atan2(attXSet, attYSet);
angle -= M_PI/2.0f;
radius *= sqrt(pow(attXSet, 2) + pow(attYSet, 2)) / sqrt(attXSaturation + attYSaturation);
p.replace(0, QPointF(xRef-maxWidth/2.0f, yRef-radius * 0.4f));
p.replace(1, QPointF(xRef-minWidth/2.0f, yRef-radius * 0.9f));
p.replace(2, QPointF(xRef+minWidth/2.0f, yRef-radius * 0.9f));
p.replace(3, QPointF(xRef+maxWidth/2.0f, yRef-radius * 0.4f));
p.replace(4, QPointF(xRef, yRef-radius * 0.36f));
p.replace(5, QPointF(xRef-maxWidth/2.0f, yRef-radius * 0.4f));
rotatePolygonClockWiseRad(p, angle, QPointF(xRef, yRef));
indexBrush.setStyle(Qt::SolidPattern);
painter->setPen(Qt::SolidLine);
painter->setBrush(indexBrush);
drawPolygon(p, painter);
//qDebug() << "DRAWING ATT SETPOINT X:" << attXSet << "Y:" << attYSet << angle;
}
void HSIDisplay::drawAltitudeSetpoint(float xRef, float yRef, float radius, const QColor& color, QPainter* painter)
{
// Draw the circle
QPen circlePen(Qt::SolidLine);
circlePen.setWidth(refLineWidthToPen(0.5f));
circlePen.setColor(color);
painter->setBrush(Qt::NoBrush);
painter->setPen(circlePen);
drawCircle(xRef, yRef, radius, 200.0f, color, painter);
//drawCircle(xRef, yRef, radius, 200.0f, 170.0f, 1.0f, color, painter);
// // Draw the value
// QString label;
// label.sprintf("%05.1f", value);
// paintText(label, color, 4.5f, xRef-7.5f, yRef-2.0f, painter);
void HSIDisplay::wheelEvent(QWheelEvent* event)
{
double zoomScale = 0.005; // Scaling of zoom value
if(event->delta() > 0)
{
// Reduce width -> Zoom in
metricWidth -= event->delta() * zoomScale;
}
else
{
// Increase width -> Zoom out
metricWidth -= event->delta() * zoomScale;
}
metricWidth = qBound(0.1, metricWidth, 9999.0);
emit metricWidthChanged(metricWidth);
}
void HSIDisplay::updateJoystick(double roll, double pitch, double yaw, double thrust, int xHat, int yHat)
{
Q_UNUSED(roll);
Q_UNUSED(pitch);
Q_UNUSED(yaw);
Q_UNUSED(thrust);
Q_UNUSED(xHat);
Q_UNUSED(yHat);
}
void HSIDisplay::pressKey(int key)
{