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

OP-1739 Add GLONASS support to GPS constellation widget

This commit is contained in:
Erik Gustavsson 2015-03-01 08:32:01 +01:00
parent 76ff576b38
commit a806eb6f36

View File

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