MainToolBarController.cc 11.4 KB
Newer Older
dogmaphobic's avatar
dogmaphobic committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
/*=====================================================================

QGroundControl Open Source Ground Control Station

(c) 2009, 2015 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 QGC Main Tool Bar
 *   @author Gus Grubba <mavlink@grubba.com>
 */

#include <QQmlContext>
#include <QQmlEngine>

33
#include "MainToolBarController.h"
Don Gagne's avatar
Don Gagne committed
34
#include "ScreenToolsController.h"
35
#include "MainWindow.h"
dogmaphobic's avatar
dogmaphobic committed
36
#include "UASMessageView.h"
37 38
#include "UASMessageHandler.h"
#include "QGCApplication.h"
39
#include "MultiVehicleManager.h"
40
#include "UAS.h"
dogmaphobic's avatar
dogmaphobic committed
41

42 43
MainToolBarController::MainToolBarController(QObject* parent)
    : QObject(parent)
44
    , _vehicle(NULL)
Don Gagne's avatar
Don Gagne committed
45
    , _mav(NULL)
dogmaphobic's avatar
dogmaphobic committed
46
    , _connectionCount(0)
47
    , _progressBarValue(0.0f)
48
    , _remoteRSSI(0)
dogmaphobic's avatar
dogmaphobic committed
49
    , _remoteRSSIstore(100.0)
50 51
    , _telemetryRRSSI(0)
    , _telemetryLRSSI(0)
dogmaphobic's avatar
dogmaphobic committed
52
    , _rollDownMessages(0)
53
    , _toolbarMessageVisible(false)
dogmaphobic's avatar
dogmaphobic committed
54 55 56
{
    emit configListChanged();
    emit connectionCountChanged(_connectionCount);
57
    _activeVehicleChanged(qgcApp()->toolbox()->multiVehicleManager()->activeVehicle());
58
    
dogmaphobic's avatar
dogmaphobic committed
59
    // Link signals
60 61 62
    connect(qgcApp()->toolbox()->linkManager(),     &LinkManager::linkConfigurationChanged, this, &MainToolBarController::_updateConfigurations);
    connect(qgcApp()->toolbox()->linkManager(),     &LinkManager::linkConnected,            this, &MainToolBarController::_linkConnected);
    connect(qgcApp()->toolbox()->linkManager(),     &LinkManager::linkDisconnected,         this, &MainToolBarController::_linkDisconnected);
63
    
64
    // RSSI (didn't like standard connection)
65
    connect(qgcApp()->toolbox()->mavlinkProtocol(),
66 67
        SIGNAL(radioStatusChanged(LinkInterface*, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned)), this,
        SLOT(_telemetryChanged(LinkInterface*, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned)));
68
    
69
    connect(qgcApp()->toolbox()->multiVehicleManager(), &MultiVehicleManager::activeVehicleChanged, this, &MainToolBarController::_activeVehicleChanged);
dogmaphobic's avatar
dogmaphobic committed
70 71
}

72
MainToolBarController::~MainToolBarController()
dogmaphobic's avatar
dogmaphobic committed
73 74 75 76
{

}

77
void MainToolBarController::onSetupView()
78
{
79
    MainWindow::instance()->showSetupView();
80 81
}

82
void MainToolBarController::onPlanView()
83
{
84
    MainWindow::instance()->showPlanView();
85 86
}

87
void MainToolBarController::onFlyView()
dogmaphobic's avatar
dogmaphobic committed
88
{
89
    MainWindow::instance()->showFlyView();
dogmaphobic's avatar
dogmaphobic committed
90 91
}

92
void MainToolBarController::onDisconnect(QString conf)
dogmaphobic's avatar
dogmaphobic committed
93
{
dogmaphobic's avatar
dogmaphobic committed
94 95 96 97
    if(conf.isEmpty()) {
        // Disconnect Only Connected Link
        int connectedCount = 0;
        LinkInterface* connectedLink = NULL;
98
        QList<LinkInterface*> links = qgcApp()->toolbox()->linkManager()->getLinks();
dogmaphobic's avatar
dogmaphobic committed
99 100 101 102
        foreach(LinkInterface* link, links) {
            if (link->isConnected()) {
                connectedCount++;
                connectedLink = link;
dogmaphobic's avatar
dogmaphobic committed
103 104
            }
        }
dogmaphobic's avatar
dogmaphobic committed
105 106 107
        Q_ASSERT(connectedCount   == 1);
        Q_ASSERT(_connectionCount == 1);
        Q_ASSERT(connectedLink);
108
        qgcApp()->toolbox()->linkManager()->disconnectLink(connectedLink);
dogmaphobic's avatar
dogmaphobic committed
109
    } else {
dogmaphobic's avatar
dogmaphobic committed
110
        // Disconnect Named Connected Link
111
        QList<LinkInterface*> links = qgcApp()->toolbox()->linkManager()->getLinks();
dogmaphobic's avatar
dogmaphobic committed
112 113 114
        foreach(LinkInterface* link, links) {
            if (link->isConnected()) {
                if(link->getLinkConfiguration() && link->getLinkConfiguration()->name() == conf) {
115
                    qgcApp()->toolbox()->linkManager()->disconnectLink(link);
dogmaphobic's avatar
dogmaphobic committed
116 117 118 119 120 121
                }
            }
        }
    }
}

122
void MainToolBarController::onConnect(QString conf)
dogmaphobic's avatar
dogmaphobic committed
123
{
dogmaphobic's avatar
dogmaphobic committed
124 125 126 127 128
    // Connect Link
    if(conf.isEmpty()) {
        MainWindow::instance()->manageLinks();
    } else {
        // We don't want the list updating under our feet
129
        qgcApp()->toolbox()->linkManager()->suspendConfigurationUpdates(true);
dogmaphobic's avatar
dogmaphobic committed
130
        // Create a link
131
        LinkInterface* link = qgcApp()->toolbox()->linkManager()->createConnectedLink(conf);
dogmaphobic's avatar
dogmaphobic committed
132 133 134 135
        if(link) {
            // Save last used connection
            MainWindow::instance()->saveLastUsedConnection(conf);
        }
136
        qgcApp()->toolbox()->linkManager()->suspendConfigurationUpdates(false);
dogmaphobic's avatar
dogmaphobic committed
137 138 139
    }
}

140
void MainToolBarController::onEnterMessageArea(int x, int y)
dogmaphobic's avatar
dogmaphobic committed
141
{
142 143 144
    Q_UNUSED(x);
    Q_UNUSED(y);

dogmaphobic's avatar
dogmaphobic committed
145
    // If not already there and messages are actually present
146 147 148
    if(!_rollDownMessages && qgcApp()->toolbox()->uasMessageHandler()->messages().count()) {
        if (qgcApp()->toolbox()->multiVehicleManager()->activeVehicle()) {
            qgcApp()->toolbox()->multiVehicleManager()->activeVehicle()->resetMessages();
149 150 151
        }

        // FIXME: Position of the message dropdown is hacked right now to speed up Qml conversion
dogmaphobic's avatar
dogmaphobic committed
152 153
        // Show messages
        int dialogWidth = 400;
154
#if 0
dogmaphobic's avatar
dogmaphobic committed
155 156 157
        x = x - (dialogWidth >> 1);
        if(x < 0) x = 0;
        y = height() / 3;
158 159
#endif

dogmaphobic's avatar
dogmaphobic committed
160
        // Put dialog on top of the message alert icon
161
        _rollDownMessages = new UASMessageViewRollDown(qgcApp()->toolbox()->uasMessageHandler(), MainWindow::instance());
dogmaphobic's avatar
dogmaphobic committed
162
        _rollDownMessages->setAttribute(Qt::WA_DeleteOnClose);
163
        _rollDownMessages->move(QPoint(100, 100));
dogmaphobic's avatar
dogmaphobic committed
164
        _rollDownMessages->setMinimumSize(dialogWidth,200);
165
        connect(_rollDownMessages, &UASMessageViewRollDown::closeWindow, this, &MainToolBarController::_leaveMessageView);
dogmaphobic's avatar
dogmaphobic committed
166 167 168 169
        _rollDownMessages->show();
    }
}

170
void MainToolBarController::_leaveMessageView()
dogmaphobic's avatar
dogmaphobic committed
171 172 173 174 175
{
    // Mouse has left the message window area (and it has closed itself)
    _rollDownMessages = NULL;
}

176
void MainToolBarController::_activeVehicleChanged(Vehicle* vehicle)
177
{
178 179
    // Disconnect the previous one (if any)
    if (_vehicle) {
180 181
        disconnect(_mav, &UASInterface::remoteControlRSSIChanged, this, &MainToolBarController::_remoteControlRSSIChanged);
        disconnect(_vehicle->autopilotPlugin(), &AutoPilotPlugin::parameterListProgress, this, &MainToolBarController::_setProgressBarValue);
182
        _mav = NULL;
183
        _vehicle = NULL;
184
    }
185
    
dogmaphobic's avatar
dogmaphobic committed
186
    // Connect new system
187
    if (vehicle)
dogmaphobic's avatar
dogmaphobic committed
188
    {
189 190
        _vehicle = vehicle;
        _mav = vehicle->uas();
191 192
        connect(_mav, &UASInterface::remoteControlRSSIChanged, this, &MainToolBarController::_remoteControlRSSIChanged);
        connect(_vehicle->autopilotPlugin(), &AutoPilotPlugin::parameterListProgress, this, &MainToolBarController::_setProgressBarValue);
dogmaphobic's avatar
dogmaphobic committed
193
    }
194 195
}

196
void MainToolBarController::_updateConfigurations()
197 198
{
    QStringList tmpList;
199
    QList<LinkConfiguration*> configs = qgcApp()->toolbox()->linkManager()->getLinkConfigurationList();
200 201 202 203 204 205 206 207 208 209 210 211 212 213
    foreach(LinkConfiguration* conf, configs) {
        if(conf) {
            if(conf->isPreferred()) {
                tmpList.insert(0,conf->name());
            } else {
                tmpList << conf->name();
            }
        }
    }
    // Any changes?
    if(tmpList != _linkConfigurations) {
        _linkConfigurations = tmpList;
        emit configListChanged();
    }
dogmaphobic's avatar
dogmaphobic committed
214 215
}

216
void MainToolBarController::_telemetryChanged(LinkInterface*, unsigned, unsigned, unsigned rssi, unsigned remrssi, unsigned, unsigned, unsigned)
217
{
218
    // We only care if we haveone single connection
219
    if(_connectionCount == 1) {
220 221 222 223 224 225 226 227 228
        if((unsigned)_telemetryLRSSI != rssi) {
            // According to the Silabs data sheet, the RSSI value is 0.5db per bit
            _telemetryLRSSI = rssi >> 1;
            emit telemetryLRSSIChanged(_telemetryLRSSI);
        }
        if((unsigned)_telemetryRRSSI != remrssi) {
            // According to the Silabs data sheet, the RSSI value is 0.5db per bit
            _telemetryRRSSI = remrssi >> 1;
            emit telemetryRRSSIChanged(_telemetryRRSSI);
229 230 231 232
        }
    }
}

233
void MainToolBarController::_remoteControlRSSIChanged(uint8_t rssi)
234
{
dogmaphobic's avatar
dogmaphobic committed
235
    // We only care if we have one single connection
236
    if(_connectionCount == 1) {
dogmaphobic's avatar
dogmaphobic committed
237 238 239 240 241 242 243 244
        // Low pass to git rid of jitter
        _remoteRSSIstore = (_remoteRSSIstore * 0.9f) + ((float)rssi * 0.1);
        uint8_t filteredRSSI = (uint8_t)ceil(_remoteRSSIstore);
        if(_remoteRSSIstore < 0.1) {
            filteredRSSI = 0;
        }
        if(_remoteRSSI != filteredRSSI) {
            _remoteRSSI = filteredRSSI;
245 246
            emit remoteRSSIChanged(_remoteRSSI);
        }
247 248 249
    }
}

250
void MainToolBarController::_linkConnected(LinkInterface*)
dogmaphobic's avatar
dogmaphobic committed
251 252 253 254
{
    _updateConnection();
}

255
void MainToolBarController::_linkDisconnected(LinkInterface* link)
dogmaphobic's avatar
dogmaphobic committed
256 257 258 259
{
    _updateConnection(link);
}

260
void MainToolBarController::_updateConnection(LinkInterface *disconnectedLink)
dogmaphobic's avatar
dogmaphobic committed
261 262 263 264 265
{
    QStringList connList;
    int oldCount = _connectionCount;
    // If there are multiple connected links add/update the connect button menu
    _connectionCount = 0;
266
    QList<LinkInterface*> links = qgcApp()->toolbox()->linkManager()->getLinks();
dogmaphobic's avatar
dogmaphobic committed
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
    foreach(LinkInterface* link, links) {
        if (disconnectedLink != link && link->isConnected()) {
            _connectionCount++;
            if(link->getLinkConfiguration()) {
                connList << link->getLinkConfiguration()->name();
            }
        }
    }
    if(oldCount != _connectionCount) {
        emit connectionCountChanged(_connectionCount);
    }
    if(connList != _connectedList) {
        _connectedList = connList;
        emit connectedListChanged(_connectedList);
    }
282
    // Update telemetry RSSI display
283 284 285 286 287 288 289
    if(_connectionCount != 1 && _telemetryRRSSI > 0) {
        _telemetryRRSSI = 0;
        emit telemetryRRSSIChanged(_telemetryRRSSI);
    }
    if(_connectionCount != 1 && _telemetryLRSSI > 0) {
        _telemetryLRSSI = 0;
        emit telemetryLRSSIChanged(_telemetryLRSSI);
290
    }
291 292
    if(_connectionCount != 1 && _remoteRSSI > 0) {
        _remoteRSSI = 0;
dogmaphobic's avatar
dogmaphobic committed
293
        emit remoteRSSIChanged(_remoteRSSI);
294
    }
dogmaphobic's avatar
dogmaphobic committed
295 296
}

297
void MainToolBarController::_setProgressBarValue(float value)
298 299 300 301
{
    _progressBarValue = value;
    emit progressBarValueChanged(value);
}
Don Gagne's avatar
Don Gagne committed
302

303
void MainToolBarController::showToolBarMessage(const QString& message)
304 305 306 307
{
    _toolbarMessageQueueMutex.lock();
    
    if (_toolbarMessageQueue.count() == 0 && !_toolbarMessageVisible) {
308
        QTimer::singleShot(500, this, &MainToolBarController::_delayedShowToolBarMessage);
309 310 311 312 313 314 315
    }
    
    _toolbarMessageQueue += message;
    
    _toolbarMessageQueueMutex.unlock();
}

316
void MainToolBarController::_delayedShowToolBarMessage(void)
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
{
    QString messages;
    
    if (!_toolbarMessageVisible) {
        _toolbarMessageQueueMutex.lock();
        
        foreach (QString message, _toolbarMessageQueue) {
            messages += message + "\n";
        }
        _toolbarMessageQueue.clear();
        
        _toolbarMessageQueueMutex.unlock();
        
        if (!messages.isEmpty()) {
            _toolbarMessageVisible = true;
            emit showMessage(messages);
        }
    }
}

337
void MainToolBarController::onToolBarMessageClosed(void)
338 339 340
{
    _toolbarMessageVisible = false;
    _delayedShowToolBarMessage();
Don Gagne's avatar
Don Gagne committed
341
}
Don Gagne's avatar
Don Gagne committed
342 343 344 345 346

void MainToolBarController::showSettings(void)
{
    MainWindow::instance()->showSettings();
}