PositionManager.cpp 4.38 KB
Newer Older
1 2 3 4 5 6 7 8
/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/
Jimmy Johnson's avatar
Jimmy Johnson committed
9 10

#include "PositionManager.h"
11 12
#include "QGCApplication.h"
#include "QGCCorePlugin.h"
Jimmy Johnson's avatar
Jimmy Johnson committed
13

14
QGCPositionManager::QGCPositionManager(QGCApplication* app, QGCToolbox* toolbox)
Don Gagne's avatar
Don Gagne committed
15 16
    : QGCTool           (app, toolbox)
    , _updateInterval   (0)
17
    , _gcsHeading       (NAN)
18 19 20 21
    , _currentSource    (nullptr)
    , _defaultSource    (nullptr)
    , _nmeaSource       (nullptr)
    , _simulatedSource  (nullptr)
Jimmy Johnson's avatar
Jimmy Johnson committed
22 23 24 25 26 27 28
{

}

QGCPositionManager::~QGCPositionManager()
{
    delete(_simulatedSource);
29
    delete(_nmeaSource);
Jimmy Johnson's avatar
Jimmy Johnson committed
30 31
}

32
void QGCPositionManager::setToolbox(QGCToolbox *toolbox)
Jimmy Johnson's avatar
Jimmy Johnson committed
33
{
34 35 36
   QGCTool::setToolbox(toolbox);
   //-- First see if plugin provides a position source
   _defaultSource = toolbox->corePlugin()->createPositionSource(this);
37 38 39 40 41 42 43

   if (qgcApp()->runningUnitTests()) {
       // Units test on travis fail due to lack of position source
       return;
   }

   if (!_defaultSource) {
44 45 46 47
       //-- Otherwise, create a default one
       _defaultSource = QGeoPositionInfoSource::createDefaultSource(this);
   }
   _simulatedSource = new SimulatedPosition();
Jimmy Johnson's avatar
Jimmy Johnson committed
48

DonLakeFlyer's avatar
DonLakeFlyer committed
49
#if 1
50
   setPositionSource(QGCPositionSource::InternalGPS);
51 52 53
#else
   setPositionSource(QGCPositionManager::Simulated);
#endif
54 55 56 57
}

void QGCPositionManager::setNmeaSourceDevice(QIODevice* device)
{
58
    // stop and release _nmeaSource
59
    if (_nmeaSource) {
60 61 62 63 64 65 66 67
        _nmeaSource->stopUpdates();
        disconnect(_nmeaSource);

        // if _currentSource is pointing there, point to null
        if (_currentSource == _nmeaSource){
            _currentSource = nullptr;
        }

68
        delete _nmeaSource;
69 70
        _nmeaSource = nullptr;

71 72 73 74
    }
    _nmeaSource = new QNmeaPositionInfoSource(QNmeaPositionInfoSource::RealTimeMode, this);
    _nmeaSource->setDevice(device);
    setPositionSource(QGCPositionManager::NmeaGPS);
75
}
Jimmy Johnson's avatar
Jimmy Johnson committed
76

77
void QGCPositionManager::_positionUpdated(const QGeoPositionInfo &update)
78
{
79 80
    _geoPositionInfo = update;

81
    QGeoCoordinate newGCSPosition = QGeoCoordinate();
82
    qreal newGCSHeading = update.attribute(QGeoPositionInfo::Direction);
83 84 85 86 87 88 89 90 91 92 93

    if (update.isValid()) {
        // Note that gcsPosition filters out possible crap values
        if (qAbs(update.coordinate().latitude()) > 0.001 && qAbs(update.coordinate().longitude()) > 0.001) {
            newGCSPosition = update.coordinate();
        }
    }
    if (newGCSPosition != _gcsPosition) {
        _gcsPosition = newGCSPosition;
        emit gcsPositionChanged(_gcsPosition);
    }
94 95 96 97
    if (newGCSHeading != _gcsHeading) {
        _gcsHeading = newGCSHeading;
        emit gcsHeadingChanged(_gcsHeading);
    }
98

Jimmy Johnson's avatar
Jimmy Johnson committed
99 100 101 102 103 104 105 106 107 108
    emit positionInfoUpdated(update);
}

int QGCPositionManager::updateInterval() const
{
    return _updateInterval;
}

void QGCPositionManager::setPositionSource(QGCPositionManager::QGCPositionSource source)
{
109
    if (_currentSource != nullptr) {
Jimmy Johnson's avatar
Jimmy Johnson committed
110
        _currentSource->stopUpdates();
111
        disconnect(_currentSource);
Jimmy Johnson's avatar
Jimmy Johnson committed
112 113
    }

114 115 116 117 118
    if (qgcApp()->runningUnitTests()) {
        // Units test on travis fail due to lack of position source
        return;
    }

Jimmy Johnson's avatar
Jimmy Johnson committed
119 120 121 122 123 124
    switch(source) {
    case QGCPositionManager::Log:
        break;
    case QGCPositionManager::Simulated:
        _currentSource = _simulatedSource;
        break;
125 126 127 128
    case QGCPositionManager::NmeaGPS:
        _currentSource = _nmeaSource;
        break;
    case QGCPositionManager::InternalGPS:
Jimmy Johnson's avatar
Jimmy Johnson committed
129 130 131 132 133
    default:        
        _currentSource = _defaultSource;
        break;
    }

134 135 136 137
    if (_currentSource != nullptr) {
        _updateInterval = _currentSource->minimumUpdateInterval();
        _currentSource->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods);
        _currentSource->setUpdateInterval(_updateInterval);
138 139
        connect(_currentSource, &QGeoPositionInfoSource::positionUpdated,       this, &QGCPositionManager::_positionUpdated);
        connect(_currentSource, SIGNAL(error(QGeoPositionInfoSource::Error)),   this, SLOT(_error(QGeoPositionInfoSource::Error)));
140
        _currentSource->startUpdates();
141
    }
Jimmy Johnson's avatar
Jimmy Johnson committed
142 143
}

144 145
void QGCPositionManager::_error(QGeoPositionInfoSource::Error positioningError)
{
146
    qWarning() << "QGCPositionManager error" << positioningError;
147
}