UASView.cc 20.7 KB
Newer Older
pixhawk's avatar
pixhawk committed
1 2 3 4 5 6 7 8 9 10 11
/*=====================================================================
PIXHAWK Micro Air Vehicle Flying Robotics Toolkit

(c) 2009, 2010 PIXHAWK PROJECT  <http://pixhawk.ethz.ch>

This file is part of the PIXHAWK project

    PIXHAWK 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.
12

pixhawk's avatar
pixhawk committed
13 14 15 16
    PIXHAWK 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.
17

pixhawk's avatar
pixhawk committed
18 19
    You should have received a copy of the GNU General Public License
    along with PIXHAWK. If not, see <http://www.gnu.org/licenses/>.
20

pixhawk's avatar
pixhawk committed
21 22 23 24
======================================================================*/

/**
 * @file
pixhawk's avatar
pixhawk committed
25
 *   @brief Implementation of one airstrip
pixhawk's avatar
pixhawk committed
26 27 28 29 30 31 32 33
 *
 *   @author Lorenz Meier <mavteam@student.ethz.ch>
 *
 */

#include <cmath>
#include <QDateTime>
#include <QDebug>
34
#include <QMenu>
35
#include <QInputDialog>
pixhawk's avatar
pixhawk committed
36

37
#include "QGC.h"
pixhawk's avatar
pixhawk committed
38 39 40
#include "MG.h"
#include "UASManager.h"
#include "UASView.h"
41
#include "UASWaypointManager.h"
42
#include "MainWindow.h"
pixhawk's avatar
pixhawk committed
43 44 45
#include "ui_UASView.h"

UASView::UASView(UASInterface* uas, QWidget *parent) :
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
        QWidget(parent),
        startTime(0),
        timeout(false),
        iconIsRed(true),
        timeRemaining(0),
        chargeLevel(0),
        uas(uas),
        load(0),
        state("UNKNOWN"),
        stateDesc(tr("Unknown state")),
        mode("MAV_MODE_UNKNOWN"),
        thrust(0),
        isActive(false),
        x(0),
        y(0),
        z(0),
        totalSpeed(0),
        lat(0),
        lon(0),
        alt(0),
        groundDistance(0),
        localFrame(false),
        removeAction(new QAction("Delete this system", this)),
        renameAction(new QAction("Rename..", this)),
        selectAction(new QAction("Control this system", this )),
        selectAirframeAction(new QAction("Choose Airframe", this)),
        setBatterySpecsAction(new QAction("Set Battery Options", this)),
        lowPowerModeEnabled(false),
        m_ui(new Ui::UASView)
{
    // FIXME XXX
    lowPowerModeEnabled = MainWindow::instance()->lowPowerModeEnabled();


pixhawk's avatar
pixhawk committed
80
    m_ui->setupUi(this);
81

pixhawk's avatar
pixhawk committed
82
    // Setup communication
pixhawk's avatar
pixhawk committed
83
    //connect(uas, SIGNAL(valueChanged(int,QString,double,quint64)), this, SLOT(receiveValue(int,QString,double,quint64)));
pixhawk's avatar
pixhawk committed
84 85 86 87 88 89 90
    connect(uas, SIGNAL(batteryChanged(UASInterface*, double, double, int)), this, SLOT(updateBattery(UASInterface*, double, double, int)));
    connect(uas, SIGNAL(heartbeat(UASInterface*)), this, SLOT(receiveHeartbeat(UASInterface*)));
    connect(uas, SIGNAL(thrustChanged(UASInterface*, double)), this, SLOT(updateThrust(UASInterface*, double)));
    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(speedChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateSpeed(UASInterface*,double,double,double,quint64)));
    connect(uas, SIGNAL(statusChanged(UASInterface*,QString,QString)), this, SLOT(updateState(UASInterface*,QString,QString)));
pixhawk's avatar
pixhawk committed
91
    connect(uas, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int,QString,QString)));
pixhawk's avatar
pixhawk committed
92
    connect(uas, SIGNAL(loadChanged(UASInterface*, double)), this, SLOT(updateLoad(UASInterface*, double)));
93
    connect(uas, SIGNAL(heartbeatTimeout()), this, SLOT(heartbeatTimeout()));
pixhawk's avatar
pixhawk committed
94
    connect(uas, SIGNAL(waypointSelected(int,int)), this, SLOT(selectWaypoint(int,int)));
pixhawk's avatar
pixhawk committed
95
    connect(uas->getWaypointManager(), SIGNAL(currentWaypointChanged(quint16)), this, SLOT(currentWaypointUpdated(quint16)));
pixhawk's avatar
pixhawk committed
96
    connect(uas, SIGNAL(systemTypeSet(UASInterface*,uint)), this, SLOT(setSystemType(UASInterface*,uint)));
97
    connect(UASManager::instance(), SIGNAL(activeUASStatusChanged(UASInterface*,bool)), this, SLOT(updateActiveUAS(UASInterface*,bool)));
98 99 100
    connect(uas, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(showStatusText(int, int, int, QString)));
    connect(uas, SIGNAL(navModeChanged(int, int, QString)), this, SLOT(updateNavMode(int, int, QString)));

pixhawk's avatar
pixhawk committed
101
    // Setup UAS selection
102
    connect(m_ui->uasViewFrame, SIGNAL(clicked(bool)), this, SLOT(setUASasActive(bool)));
103

pixhawk's avatar
pixhawk committed
104 105 106 107
    // Setup user interaction
    connect(m_ui->liftoffButton, SIGNAL(clicked()), uas, SLOT(launch()));
    connect(m_ui->haltButton, SIGNAL(clicked()), uas, SLOT(halt()));
    connect(m_ui->continueButton, SIGNAL(clicked()), uas, SLOT(go()));
pixhawk's avatar
pixhawk committed
108 109
    connect(m_ui->landButton, SIGNAL(clicked()), uas, SLOT(home()));
    connect(m_ui->abortButton, SIGNAL(clicked()), uas, SLOT(emergencySTOP()));
pixhawk's avatar
pixhawk committed
110 111
    connect(m_ui->killButton, SIGNAL(clicked()), uas, SLOT(emergencyKILL()));
    connect(m_ui->shutdownButton, SIGNAL(clicked()), uas, SLOT(shutdown()));
112 113 114

    // Allow to delete this widget
    connect(removeAction, SIGNAL(triggered()), this, SLOT(deleteLater()));
115
    connect(renameAction, SIGNAL(triggered()), this, SLOT(rename()));
116
    connect(selectAction, SIGNAL(triggered()), uas, SLOT(setSelected()));
117
    connect(selectAirframeAction, SIGNAL(triggered()), this, SLOT(selectAirframe()));
118
    connect(setBatterySpecsAction, SIGNAL(triggered()), this, SLOT(setBatterySpecs()));
119
    connect(uas, SIGNAL(systemRemoved()), this, SLOT(deleteLater()));
120 121 122

    // Name changes
    connect(uas, SIGNAL(nameChanged(QString)), this, SLOT(updateName(QString)));
123

pixhawk's avatar
pixhawk committed
124
    // Set static values
125

pixhawk's avatar
pixhawk committed
126
    // Name
127
    if (uas->getUASName() == "") {
pixhawk's avatar
pixhawk committed
128
        m_ui->nameLabel->setText(tr("UAS") + QString::number(uas->getUASID()));
129
    } else {
pixhawk's avatar
pixhawk committed
130 131
        m_ui->nameLabel->setText(uas->getUASName());
    }
132

133
    setBackgroundColor();
134

pixhawk's avatar
pixhawk committed
135 136 137
    // Heartbeat fade
    refreshTimer = new QTimer(this);
    connect(refreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
138 139 140 141 142 143
    if (lowPowerModeEnabled)
    {
        refreshTimer->start(updateInterval*10);
    } else {
        refreshTimer->start(updateInterval);
    }
144 145 146 147 148

    // Hide kill and shutdown buttons per default
    m_ui->killButton->hide();
    m_ui->shutdownButton->hide();

149
    setSystemType(uas, uas->getSystemType());
pixhawk's avatar
pixhawk committed
150 151 152 153 154
}

UASView::~UASView()
{
    delete m_ui;
155 156 157
    delete removeAction;
    delete renameAction;
    delete selectAction;
pixhawk's avatar
pixhawk committed
158 159
}

160 161 162 163
void UASView::heartbeatTimeout()
{
    timeout = true;
}
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179

void UASView::updateNavMode(int uasid, int mode, const QString& text)
{
    Q_UNUSED(uasid);
    Q_UNUSED(mode);
    m_ui->navLabel->setText(text);
}

void UASView::showStatusText(int uasid, int componentid, int severity, QString text)
{
    Q_UNUSED(uasid);
    Q_UNUSED(componentid);
    Q_UNUSED(severity);
    //m_ui->statusTextLabel->setText(text);
    stateDesc = text;
}
180

181 182 183 184 185 186 187 188 189 190
/**
 * Set the background color based on the MAV color. If the MAV is selected as the
 * currently actively controlled system, the frame color is highlighted
 */
void UASView::setBackgroundColor()
{
    // UAS color
    QColor uasColor = uas->getColor();
    QString colorstyle;
    QString borderColor = "#4A4A4F";
191
    if (isActive) {
192 193
        borderColor = "#FA4A4F";
        uasColor = uasColor.darker(475);
194
    } else {
195 196
        uasColor = uasColor.darker(675);
    }
197
    colorstyle = colorstyle.sprintf("QGroupBox { border-radius: 12px; padding: 0px; margin: 0px; background-color: #%02X%02X%02X; border: 2px solid %s; }",
198 199 200 201 202
                                    uasColor.red(), uasColor.green(), uasColor.blue(), borderColor.toStdString().c_str());
    m_ui->uasViewFrame->setStyleSheet(colorstyle);
}

void UASView::setUASasActive(bool active)
pixhawk's avatar
pixhawk committed
203
{
204
    if (active) {
205 206 207 208 209 210
        UASManager::instance()->setActiveUAS(this->uas);
    }
}

void UASView::updateActiveUAS(UASInterface* uas, bool active)
{
211
    if (uas == this->uas) {
212 213 214
        this->isActive = active;
        setBackgroundColor();
    }
pixhawk's avatar
pixhawk committed
215 216
}

pixhawk's avatar
pixhawk committed
217 218
void UASView::updateMode(int sysId, QString status, QString description)
{
219
    Q_UNUSED(description);
220 221

    //int aa=this->uas->getUASID();
pixhawk's avatar
pixhawk committed
222
    if (sysId == this->uas->getUASID()) m_ui->modeLabel->setText(status);
223 224

    m_ui->modeLabel->setText(status);
pixhawk's avatar
pixhawk committed
225 226
}

pixhawk's avatar
pixhawk committed
227 228
void UASView::mouseDoubleClickEvent (QMouseEvent * event)
{
229
    Q_UNUSED(event);
pixhawk's avatar
pixhawk committed
230 231 232 233 234 235
    UASManager::instance()->setActiveUAS(uas);
    qDebug() << __FILE__ << __LINE__ << "DOUBLECLICKED";
}

void UASView::enterEvent(QEvent* event)
{
236
    if (event->type() == QEvent::MouseMove) {
237
        emit uasInFocus(uas);
238
        if (uas != UASManager::instance()->getActiveUAS()) {
239 240 241
            grabMouse(QCursor(Qt::PointingHandCursor));
        }
    }
pixhawk's avatar
pixhawk committed
242
    qDebug() << __FILE__ << __LINE__ << "IN FOCUS";
243 244

    if (event->type() == QEvent::MouseButtonDblClick) {
245 246
        qDebug() << __FILE__ << __LINE__ << "UAS CLICKED!";
    }
pixhawk's avatar
pixhawk committed
247 248 249 250
}

void UASView::leaveEvent(QEvent* event)
{
251
    if (event->type() == QEvent::MouseMove) {
252 253 254 255 256 257 258 259 260
        emit uasOutFocus(uas);
        releaseMouse();
    }
}

void UASView::showEvent(QShowEvent* event)
{
    // React only to internal (pre-display)
    // events
261
    Q_UNUSED(event);
262
    refreshTimer->start(updateInterval*10);
263 264 265 266 267 268 269 270
}

void UASView::hideEvent(QHideEvent* event)
{
    // React only to internal (pre-display)
    // events
    Q_UNUSED(event);
    refreshTimer->stop();
pixhawk's avatar
pixhawk committed
271 272 273 274
}

void UASView::receiveHeartbeat(UASInterface* uas)
{
275
    Q_UNUSED(uas);
276
    heartbeatColor = QColor(20, 200, 20);
lm's avatar
lm committed
277
    QString colorstyle("QGroupBox { border-radius: 5px; padding: 2px; margin: 0px; border: 0px; background-color: %1; }");
278
    m_ui->heartbeatIcon->setStyleSheet(colorstyle.arg(heartbeatColor.name()));
279 280 281 282 283 284
    if (timeout) setBackgroundColor();
    timeout = false;
}

void UASView::updateName(const QString& name)
{
285
    if (uas) m_ui->nameLabel->setText(name);
pixhawk's avatar
pixhawk committed
286 287 288 289 290 291 292 293 294 295 296
}

/**
 * The current system type is represented through the system icon.
 *
 * @param uas Source system, has to be the same as this->uas
 * @param systemType type ID, following the MAVLink system type conventions
 * @see http://pixhawk.ethz.ch/software/mavlink
 */
void UASView::setSystemType(UASInterface* uas, unsigned int systemType)
{
297
    if (uas == this->uas) {
pixhawk's avatar
pixhawk committed
298
        // Set matching icon
299
        switch (systemType) {
pixhawk's avatar
pixhawk committed
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
        case 0:
            m_ui->typeButton->setIcon(QIcon(":/images/mavs/generic.svg"));
            break;
        case 1:
            m_ui->typeButton->setIcon(QIcon(":/images/mavs/fixed-wing.svg"));
            break;
        case 2:
            m_ui->typeButton->setIcon(QIcon(":/images/mavs/quadrotor.svg"));
            break;
        case 3:
            m_ui->typeButton->setIcon(QIcon(":/images/mavs/coaxial.svg"));
            break;
        case 4:
            m_ui->typeButton->setIcon(QIcon(":/images/mavs/helicopter.svg"));
            break;
        case 5:
lm's avatar
lm committed
316 317
            m_ui->typeButton->setIcon(QIcon(":/images/mavs/unknown.svg"));
            break;
318
        case 6: {
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
                // A groundstation is a special system type, update widget
                QString result;
                m_ui->nameLabel->setText(tr("OCU ") + result.sprintf("%03d", uas->getUASID()));
                m_ui->waypointLabel->setText("");
                m_ui->timeRemainingLabel->setText("Online:");
                m_ui->batteryBar->hide();
                m_ui->thrustBar->hide();
                m_ui->stateLabel->hide();
                m_ui->statusTextLabel->hide();
                m_ui->waypointLabel->hide();
                m_ui->liftoffButton->hide();
                m_ui->haltButton->hide();
                m_ui->landButton->hide();
                m_ui->shutdownButton->hide();
                m_ui->abortButton->hide();
                m_ui->typeButton->setIcon(QIcon(":/images/mavs/groundstation.svg"));
            }
            break;
pixhawk's avatar
pixhawk committed
337 338 339 340 341 342 343 344 345
        default:
            m_ui->typeButton->setIcon(QIcon(":/images/mavs/unknown.svg"));
            break;
        }
    }
}

void UASView::updateLocalPosition(UASInterface* uas, double x, double y, double z, quint64 usec)
{
346
    Q_UNUSED(usec);
347 348 349 350
    Q_UNUSED(uas);
    this->x = x;
    this->y = y;
    this->z = z;
351
    if (!localFrame) {
352
        localFrame = true;
pixhawk's avatar
pixhawk committed
353 354 355
    }
}

356
void UASView::updateGlobalPosition(UASInterface* uas, double lon, double lat, double alt, quint64 usec)
pixhawk's avatar
pixhawk committed
357
{
358 359
    Q_UNUSED(uas);
    Q_UNUSED(usec);
pixhawk's avatar
pixhawk committed
360 361 362
    this->lon = lon;
    this->lat = lat;
    this->alt = alt;
pixhawk's avatar
pixhawk committed
363 364 365 366
}

void UASView::updateSpeed(UASInterface*, double x, double y, double z, quint64 usec)
{
367
    Q_UNUSED(usec);
368
    totalSpeed = sqrt(x*x + y*y + z*z);
pixhawk's avatar
pixhawk committed
369 370
}

371 372 373 374 375
void UASView::currentWaypointUpdated(quint16 waypoint)
{
    m_ui->waypointLabel->setText(tr("WP") + QString::number(waypoint));
}

pixhawk's avatar
pixhawk committed
376 377
void UASView::setWaypoint(int uasId, int id, double x, double y, double z, double yaw, bool autocontinue, bool current)
{
378 379 380 381 382
    Q_UNUSED(x);
    Q_UNUSED(y);
    Q_UNUSED(z);
    Q_UNUSED(yaw);
    Q_UNUSED(autocontinue);
383 384
    if (uasId == this->uas->getUASID()) {
        if (current) {
pixhawk's avatar
pixhawk committed
385 386 387 388 389 390 391
            m_ui->waypointLabel->setText(tr("WP") + QString::number(id));
        }
    }
}

void UASView::selectWaypoint(int uasId, int id)
{
392
    if (uasId == this->uas->getUASID()) {
pixhawk's avatar
pixhawk committed
393 394 395 396 397 398
        m_ui->waypointLabel->setText(tr("WP") + QString::number(id));
    }
}

void UASView::updateThrust(UASInterface* uas, double thrust)
{
399
    if (this->uas == uas) {
pixhawk's avatar
pixhawk committed
400
        this->thrust = thrust;
pixhawk's avatar
pixhawk committed
401 402 403 404 405
    }
}

void UASView::updateBattery(UASInterface* uas, double voltage, double percent, int seconds)
{
406
    Q_UNUSED(voltage);
407
    if (this->uas == uas) {
pixhawk's avatar
pixhawk committed
408 409 410 411 412 413 414
        timeRemaining = seconds;
        chargeLevel = percent;
    }
}

void UASView::updateState(UASInterface* uas, QString uasState, QString stateDescription)
{
415
    if (this->uas == uas) {
pixhawk's avatar
pixhawk committed
416 417 418 419 420 421 422
        state = uasState;
        stateDesc = stateDescription;
    }
}

void UASView::updateLoad(UASInterface* uas, double load)
{
423
    if (this->uas == uas) {
pixhawk's avatar
pixhawk committed
424 425 426 427
        this->load = load;
    }
}

428 429
void UASView::contextMenuEvent (QContextMenuEvent* event)
{
430
    QMenu menu(this);
lm's avatar
lm committed
431 432
    menu.addAction(selectAction);
    menu.addSeparator();
433
    menu.addAction(renameAction);
434
    if (timeout) {
435
        menu.addAction(removeAction);
436
    }
437
    menu.addAction(selectAirframeAction);
438
    menu.addAction(setBatterySpecsAction);
439 440 441
    menu.exec(event->globalPos());
}

442 443
void UASView::setBatterySpecs()
{
444
    if (uas) {
445 446
        bool ok;
        QString newName = QInputDialog::getText(this, tr("Set Battery Specifications for %1").arg(uas->getUASName()),
447
                                                tr("Specs: (empty,warn,full), e.g. (9V,9.5V,12.6V) or just warn level in percent (e.g. 15%) to use estimate from MAV"), QLineEdit::Normal,
448 449 450 451 452 453
                                                uas->getBatterySpecs(), &ok);

        if (ok && !newName.isEmpty()) uas->setBatterySpecs(newName);
    }
}

454 455
void UASView::rename()
{
456
    if (uas) {
457 458 459 460 461 462
        bool ok;
        QString newName = QInputDialog::getText(this, tr("Rename System %1").arg(uas->getUASName()),
                                                tr("System Name:"), QLineEdit::Normal,
                                                uas->getUASName(), &ok);

        if (ok && !newName.isEmpty()) uas->setUASName(newName);
463 464 465
    }
}

466 467
void UASView::selectAirframe()
{
468
    if (uas) {
469 470 471
        // Get list of airframes from UAS
        QStringList airframes;
        airframes << "Generic"
472 473 474 475 476 477 478 479 480
                << "Multiplex Easystar"
                << "Multiplex Twinstar"
                << "Multiplex Merlin"
                << "Pixhawk Cheetah"
                << "Mikrokopter"
                << "Reaper"
                << "Predator"
                << "Coaxial"
                << "Pteryx";
481 482 483 484

        bool ok;
        QString item = QInputDialog::getItem(this, tr("Select Airframe for %1").arg(uas->getUASName()),
                                             tr("Airframe"), airframes, uas->getAirframe(), false, &ok);
485
        if (ok && !item.isEmpty()) {
486 487 488 489 490 491
            // Set this airframe as UAS airframe
            uas->setAirframe(airframes.indexOf(item));
        }
    }
}

pixhawk's avatar
pixhawk committed
492 493
void UASView::refresh()
{
494
    //setUpdatesEnabled(false);
495 496
    //setUpdatesEnabled(true);
    //repaint();
497 498

    static quint64 lastupdate = 0;
pixhawk's avatar
pixhawk committed
499
    //qDebug() << "UASVIEW update diff: " << MG::TIME::getGroundTimeNow() - lastupdate;
500 501 502 503 504
    lastupdate = MG::TIME::getGroundTimeNow();

    // FIXME
    static int generalUpdateCount = 0;

505
    if (generalUpdateCount == 4) {
506 507 508
#if (QGC_EVENTLOOP_DEBUG)
        qDebug() << "EVENTLOOP:" << __FILE__ << __LINE__;
#endif
509
        generalUpdateCount = 0;
pixhawk's avatar
pixhawk committed
510
        //qDebug() << "UPDATING EVERYTHING";
511 512 513 514 515 516 517 518 519 520 521
        // State
        m_ui->stateLabel->setText(state);
        m_ui->statusTextLabel->setText(stateDesc);

        // Battery
        m_ui->batteryBar->setValue(static_cast<int>(this->chargeLevel));
        //m_ui->loadBar->setValue(static_cast<int>(this->load));
        m_ui->thrustBar->setValue(this->thrust);

        // Position
        QString position;
522
        position = position.sprintf("%05.1f %05.1f %06.1f m", x, y, z);
523 524 525
        m_ui->positionLabel->setText(position);
        QString globalPosition;
        QString latIndicator;
526
        if (lat > 0) {
527
            latIndicator = "N";
528
        } else {
529 530 531
            latIndicator = "S";
        }
        QString lonIndicator;
532
        if (lon > 0) {
533
            lonIndicator = "E";
534
        } else {
535 536
            lonIndicator = "W";
        }
537 538
        globalPosition = globalPosition.sprintf("%05.1f%s %05.1f%s %06.1f m", lon, lonIndicator.toStdString().c_str(), lat, latIndicator.toStdString().c_str(), alt);
        m_ui->positionLabel->setText(globalPosition);
pixhawk's avatar
pixhawk committed
539

540
        // Altitude
541
        if (groundDistance == 0 && alt != 0) {
542
            m_ui->groundDistanceLabel->setText(QString("%1 m").arg(alt, 6, 'f', 1, '0'));
543
        } else {
544
            m_ui->groundDistanceLabel->setText(QString("%1 m").arg(groundDistance, 6, 'f', 1, '0'));
545
        }
546

547
        // Speed
548 549
        QString speed("%1 m/s");
        m_ui->speedLabel->setText(speed.arg(totalSpeed, 4, 'f', 1, '0'));
pixhawk's avatar
pixhawk committed
550

551 552
        // Thrust
        m_ui->thrustBar->setValue(thrust * 100);
pixhawk's avatar
pixhawk committed
553

554
        if(this->timeRemaining > 1 && this->timeRemaining < QGC::MAX_FLIGHT_TIME) {
555 556 557 558 559 560 561 562 563 564
            // Filter output to get a higher stability
            static double filterTime = static_cast<int>(this->timeRemaining);
            filterTime = 0.8 * filterTime + 0.2 * static_cast<int>(this->timeRemaining);
            int sec = static_cast<int>(filterTime - static_cast<int>(filterTime / 60.0f) * 60);
            int min = static_cast<int>(filterTime / 60);
            int hours = static_cast<int>(filterTime - min * 60 - sec);

            QString timeText;
            timeText = timeText.sprintf("%02d:%02d:%02d", hours, min, sec);
            m_ui->timeRemainingLabel->setText(timeText);
565
        } else {
566
            m_ui->timeRemainingLabel->setText(tr("Calc.."));
567 568 569 570 571 572 573
        }

        // Time Elapsed
        //QDateTime time = MG::TIME::msecToQDateTime(uas->getUptime());

        quint64 filterTime = uas->getUptime() / 1000;
        int sec = static_cast<int>(filterTime - static_cast<int>(filterTime / 60) * 60);
pixhawk's avatar
pixhawk committed
574 575 576 577
        int min = static_cast<int>(filterTime / 60);
        int hours = static_cast<int>(filterTime - min * 60 - sec);
        QString timeText;
        timeText = timeText.sprintf("%02d:%02d:%02d", hours, min, sec);
578
        m_ui->timeElapsedLabel->setText(timeText);
pixhawk's avatar
pixhawk committed
579
    }
580
    generalUpdateCount++;
pixhawk's avatar
pixhawk committed
581

lm's avatar
lm committed
582
    QString colorstyle("QGroupBox { border-radius: 5px; padding: 2px; margin: 0px; border: 0px; background-color: %1; }");
583

584
    if (timeout) {
585 586
        // CRITICAL CONDITION, NO HEARTBEAT

587
        QString borderColor = "#FFFF00";
588
        if (isActive) {
589 590 591
            borderColor = "#FA4A4F";
        }

592
        if (iconIsRed) {
593 594
            QColor warnColor(Qt::red);
            m_ui->heartbeatIcon->setStyleSheet(colorstyle.arg(warnColor.name()));
595
            QString style = QString("QGroupBox { border-radius: 12px; padding: 0px; margin: 0px; border: 2px solid %1; background-color: %2; }").arg(borderColor, warnColor.name());
596
            m_ui->uasViewFrame->setStyleSheet(style);
597
        } else {
598 599
            QColor warnColor(Qt::black);
            m_ui->heartbeatIcon->setStyleSheet(colorstyle.arg(warnColor.name()));
600
            QString style = QString("QGroupBox { border-radius: 12px; padding: 0px; margin: 0px; border: 2px solid %1; background-color: %2; }").arg(borderColor, warnColor.name());
601 602 603
            m_ui->uasViewFrame->setStyleSheet(style);
        }
        iconIsRed = !iconIsRed;
604
    } else {
605 606 607 608 609 610 611 612 613
        if (!lowPowerModeEnabled)
        {
            // Fade heartbeat icon
            // Make color darker
            heartbeatColor = heartbeatColor.darker(150);

            //m_ui->heartbeatIcon->setAutoFillBackground(true);
            m_ui->heartbeatIcon->setStyleSheet(colorstyle.arg(heartbeatColor.name()));
        }
614
    }
615
    //setUpdatesEnabled(true);
616 617

    //setUpdatesEnabled(false);
pixhawk's avatar
pixhawk committed
618 619 620 621 622 623 624 625 626 627 628 629 630
}

void UASView::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}