diff --git a/ground/openpilotgcs/src/plugins/gpsdisplay/gpsconstellationwidget.cpp b/ground/openpilotgcs/src/plugins/gpsdisplay/gpsconstellationwidget.cpp index 08406283f..667727b99 100644 --- a/ground/openpilotgcs/src/plugins/gpsdisplay/gpsconstellationwidget.cpp +++ b/ground/openpilotgcs/src/plugins/gpsdisplay/gpsconstellationwidget.cpp @@ -1,193 +1,199 @@ -/** - ****************************************************************************** - * - * @file gpsconstellationwidget.cpp - * @author Edouard Lafargue Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup GPSGadgetPlugin GPS Gadget Plugin - * @{ - * @brief A widget which displays the GPS constellation - *****************************************************************************/ -/* - * This program 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. - * - * This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "gpsconstellationwidget.h" - -#include -#include - -/* - * Initialize the widget - */ -GpsConstellationWidget::GpsConstellationWidget(QWidget *parent) : QGraphicsView(parent) -{ - // Create a layout, add a QGraphicsView and put the SVG inside. - // The constellation widget looks like this: - // |--------------------| - // | | - // | | - // | Constellation | - // | | - // | | - // | | - // |--------------------| - - - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - QSvgRenderer *renderer = new QSvgRenderer(); - renderer->load(QString(":/gpsgadget/images/gpsEarth.svg")); - - world = new QGraphicsSvgItem(); - world->setSharedRenderer(renderer); - world->setElementId("map"); - - scene = new QGraphicsScene(this); - scene->addItem(world); - scene->setSceneRect(world->boundingRect()); - setScene(scene); - - QFontDatabase::addApplicationFont(":/gpsgadget/font/digital-7.ttf"); - - // Now create 'maxSatellites' satellite icons which we will move around on the map: - for (int i = 0; i < MAX_SATTELITES; i++) { - satellites[i][0] = 0; - satellites[i][1] = 0; - satellites[i][2] = 0; - satellites[i][3] = 0; - - satIcons[i] = new QGraphicsSvgItem(world); - satIcons[i]->setSharedRenderer(renderer); - satIcons[i]->setElementId("sat-notSeen"); - satIcons[i]->hide(); - - satTexts[i] = new QGraphicsSimpleTextItem("##", satIcons[i]); - satTexts[i]->setBrush(QColor("Black")); - satTexts[i]->setFont(QFont("Digital-7")); - } -} - -GpsConstellationWidget::~GpsConstellationWidget() -{ - delete scene; - scene = 0; - - // delete renderer; - // renderer = 0; -} - -void GpsConstellationWidget::showEvent(QShowEvent *event) -{ - Q_UNUSED(event) - // Thit fitInView method should only be called now, once the - // widget is shown, otherwise it cannot compute its values and - // the result is usually a ahrsbargraph that is way too small. - fitInView(world, Qt::KeepAspectRatio); - // Scale, can't use fitInView since that doesn't work until we're shown. - // qreal factor = height()/world->boundingRect().height(); -// world->setScale(factor); -// setSceneRect(world->boundingRect()); -} - -void GpsConstellationWidget::resizeEvent(QResizeEvent *event) -{ - Q_UNUSED(event); - fitInView(world, Qt::KeepAspectRatio); -} - -void GpsConstellationWidget::updateSat(int index, int prn, int elevation, int azimuth, int snr) -{ - if (index >= MAX_SATTELITES) { - // A bit of error checking never hurts. - return; - } - - // TODO: add range checking - satellites[index][0] = prn; - satellites[index][1] = elevation; - satellites[index][2] = azimuth; - satellites[index][3] = snr; - - if (prn && elevation >= 0) { - QPointF opd = polarToCoord(elevation, azimuth); - opd += QPointF(-satIcons[index]->boundingRect().center().x(), - -satIcons[index]->boundingRect().center().y()); - satIcons[index]->setTransform(QTransform::fromTranslate(opd.x(), opd.y()), false); - - // Show normal GPS or SBAS (120 - 158 range) - if (prn > 119 && prn < 159) { - if (snr) { - satIcons[index]->setElementId("satellite-sbas"); - } else { - satIcons[index]->setElementId("sat-sbas-notSeen"); - } - } else { - if (snr) { - satIcons[index]->setElementId("satellite"); - } else { - satIcons[index]->setElementId("sat-notSeen"); - } - } - satIcons[index]->show(); - - QRectF iconRect = satIcons[index]->boundingRect(); - QString prnString = QString().number(prn); - if (prnString.length() == 1) { - prnString = "0" + prnString; - } - satTexts[index]->setText(prnString); - QRectF textRect = satTexts[index]->boundingRect(); - - // Fixed scale, looks better for numbers 01,11,126... - qreal scale = 1.40; - - QTransform matrix; - matrix.translate(iconRect.width() / 2, iconRect.height() / 2); - matrix.scale(scale, scale); - matrix.translate(-textRect.width() / 2, -textRect.height() / 2); - satTexts[index]->setTransform(matrix, false); - } else { - satIcons[index]->hide(); - } -} - -/** - Converts the elevation/azimuth to X/Y coordinates on the map - - */ -QPointF GpsConstellationWidget::polarToCoord(int elevation, int azimuth) -{ - double x; - double y; - double vect_elevation; - double rad_azimuth; - - // Vector modulus scaled to circle and angle (azimut) - vect_elevation = 0.79 - (elevation / 90.00f) * 0.79; - rad_azimuth = M_PI * azimuth / 180; - - // Cartesian coordinates - x = ((world->boundingRect().width() * vect_elevation) / 2) * sin(rad_azimuth); - y = ((world->boundingRect().height() * vect_elevation) / 2) * -cos(rad_azimuth); - - // Start from center - x = (world->boundingRect().width() / 2) + x; - y = (world->boundingRect().height() / 2) + y; - - return QPointF(x, y); -} +/** + ****************************************************************************** + * + * @file gpsconstellationwidget.cpp + * @author Edouard Lafargue Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup GPSGadgetPlugin GPS Gadget Plugin + * @{ + * @brief A widget which displays the GPS constellation + *****************************************************************************/ +/* + * This program 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. + * + * This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "gpsconstellationwidget.h" + +#include +#include + +/* + * Initialize the widget + */ +GpsConstellationWidget::GpsConstellationWidget(QWidget *parent) : QGraphicsView(parent) +{ + // Create a layout, add a QGraphicsView and put the SVG inside. + // The constellation widget looks like this: + // |--------------------| + // | | + // | | + // | Constellation | + // | | + // | | + // | | + // |--------------------| + + + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + QSvgRenderer *renderer = new QSvgRenderer(); + renderer->load(QString(":/gpsgadget/images/gpsEarth.svg")); + + world = new QGraphicsSvgItem(); + world->setSharedRenderer(renderer); + world->setElementId("map"); + + scene = new QGraphicsScene(this); + scene->addItem(world); + scene->setSceneRect(world->boundingRect()); + setScene(scene); + + QFontDatabase::addApplicationFont(":/gpsgadget/font/digital-7.ttf"); + + // Now create 'maxSatellites' satellite icons which we will move around on the map: + for (int i = 0; i < MAX_SATTELITES; i++) { + satellites[i][0] = 0; + satellites[i][1] = 0; + satellites[i][2] = 0; + satellites[i][3] = 0; + + satIcons[i] = new QGraphicsSvgItem(world); + satIcons[i]->setSharedRenderer(renderer); + satIcons[i]->setElementId("sat-notSeen"); + satIcons[i]->hide(); + + satTexts[i] = new QGraphicsSimpleTextItem("##", satIcons[i]); + satTexts[i]->setBrush(QColor("Black")); + satTexts[i]->setFont(QFont("Digital-7")); + } +} + +GpsConstellationWidget::~GpsConstellationWidget() +{ + delete scene; + scene = 0; + + // delete renderer; + // renderer = 0; +} + +void GpsConstellationWidget::showEvent(QShowEvent *event) +{ + Q_UNUSED(event) + // Thit fitInView method should only be called now, once the + // widget is shown, otherwise it cannot compute its values and + // the result is usually a ahrsbargraph that is way too small. + fitInView(world, Qt::KeepAspectRatio); + // Scale, can't use fitInView since that doesn't work until we're shown. + // qreal factor = height()/world->boundingRect().height(); +// world->setScale(factor); +// setSceneRect(world->boundingRect()); +} + +void GpsConstellationWidget::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + fitInView(world, Qt::KeepAspectRatio); +} + +void GpsConstellationWidget::updateSat(int index, int prn, int elevation, int azimuth, int snr) +{ + if (index >= MAX_SATTELITES) { + // A bit of error checking never hurts. + return; + } + + // TODO: add range checking + satellites[index][0] = prn; + satellites[index][1] = elevation; + satellites[index][2] = azimuth; + satellites[index][3] = snr; + + if (prn && elevation >= 0) { + QPointF opd = polarToCoord(elevation, azimuth); + opd += QPointF(-satIcons[index]->boundingRect().center().x(), + -satIcons[index]->boundingRect().center().y()); + satIcons[index]->setTransform(QTransform::fromTranslate(opd.x(), opd.y()), false); + + // Show normal GPS, SBAS (120 - 158 range) or GLONASS (65 - 96, 255 if unidentified) + if (prn > 119 && prn < 159) { + if (snr) { + satIcons[index]->setElementId("satellite-sbas"); + } else { + satIcons[index]->setElementId("sat-sbas-notSeen"); + } + } else if ((prn > 64 && prn < 97) || 255 == prn) { + if (snr) { + satIcons[index]->setElementId("satellite-glonass"); + } else { + satIcons[index]->setElementId("sat-glonass-notSeen"); + } + } else { + if (snr) { + satIcons[index]->setElementId("satellite"); + } else { + satIcons[index]->setElementId("sat-notSeen"); + } + } + satIcons[index]->show(); + + QRectF iconRect = satIcons[index]->boundingRect(); + QString prnString = QString().number(prn); + if (prnString.length() == 1) { + prnString = "0" + prnString; + } + satTexts[index]->setText(prnString); + QRectF textRect = satTexts[index]->boundingRect(); + + // Fixed scale, looks better for numbers 01,11,126... + qreal scale = 1.40; + + QTransform matrix; + matrix.translate(iconRect.width() / 2, iconRect.height() / 2); + matrix.scale(scale, scale); + matrix.translate(-textRect.width() / 2, -textRect.height() / 2); + satTexts[index]->setTransform(matrix, false); + } else { + satIcons[index]->hide(); + } +} + +/** + Converts the elevation/azimuth to X/Y coordinates on the map + + */ +QPointF GpsConstellationWidget::polarToCoord(int elevation, int azimuth) +{ + double x; + double y; + double vect_elevation; + double rad_azimuth; + + // Vector modulus scaled to circle and angle (azimut) + vect_elevation = 0.79 - (elevation / 90.00f) * 0.79; + rad_azimuth = M_PI * azimuth / 180; + + // Cartesian coordinates + x = ((world->boundingRect().width() * vect_elevation) / 2) * sin(rad_azimuth); + y = ((world->boundingRect().height() * vect_elevation) / 2) * -cos(rad_azimuth); + + // Start from center + x = (world->boundingRect().width() / 2) + x; + y = (world->boundingRect().height() / 2) + y; + + return QPointF(x, y); +}