Commit 94348cb7 authored by pixhawk's avatar pixhawk

Added not yet working version of logging / log replay, fixed ALL bugs in main...

Added not yet working version of logging / log replay, fixed ALL bugs in main window, enabled full persistence in main window and serial link.
parent b54faa4b
......@@ -153,7 +153,8 @@ FORMS += src/ui/MainWindow.ui \
src/ui/uas/QGCUnconnectedInfoWidget.ui \
src/ui/designer/QGCToolWidget.ui \
src/ui/designer/QGCParamSlider.ui \
src/ui/designer/QGCActionButton.ui
src/ui/designer/QGCActionButton.ui \
src/ui/QGCMAVLinkLogPlayer.ui
INCLUDEPATH += src \
src/ui \
......@@ -259,7 +260,8 @@ HEADERS += src/MG.h \
src/ui/designer/QGCToolWidget.h \
src/ui/designer/QGCParamSlider.h \
src/ui/designer/QGCActionButton.h \
src/ui/designer/QGCToolWidgetItem.h
src/ui/designer/QGCToolWidgetItem.h \
src/ui/QGCMAVLinkLogPlayer.h
# Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler
macx|win32-msvc2008: {
......@@ -380,7 +382,8 @@ SOURCES += src/main.cc \
src/ui/designer/QGCToolWidget.cc \
src/ui/designer/QGCParamSlider.cc \
src/ui/designer/QGCActionButton.cc \
src/ui/designer/QGCToolWidgetItem.cc
src/ui/designer/QGCToolWidgetItem.cc \
src/ui/QGCMAVLinkLogPlayer.cc
macx|win32-msvc2008: {
SOURCES += src/ui/map3D/QGCGoogleEarthView.cc
......
......@@ -3,6 +3,7 @@
#include <QDateTime>
#include <QColor>
#include <QThread>
namespace QGC
{
......@@ -20,6 +21,36 @@ namespace QGC
const QString APPNAME = "QGROUNDCONTROL";
const QString COMPANYNAME = "OPENMAV";
const int APPLICATIONVERSION = 80; // 0.8.0
class SLEEP : public QThread
{
public:
/**
* @brief Set a thread to sleep for seconds
* @param s time in seconds to sleep
**/
static void sleep(unsigned long s)
{
QThread::sleep(s);
}
/**
* @brief Set a thread to sleep for milliseconds
* @param ms time in milliseconds to sleep
**/
static void msleep(unsigned long ms)
{
QThread::msleep(ms);
}
/**
* @brief Set a thread to sleep for microseconds
* @param us time in microseconds to sleep
**/
static void usleep(unsigned long us)
{
QThread::usleep(us);
}
};
}
#define QGC_EVENTLOOP_DEBUG 0
......
......@@ -59,7 +59,7 @@ MAVLinkProtocol::MAVLinkProtocol() :
heartbeatRate(MAVLINK_HEARTBEAT_DEFAULT_RATE),
m_heartbeatsEnabled(false),
m_loggingEnabled(false),
m_logfile(NULL),
m_logfile(new QFile(QCoreApplication::applicationDirPath()+"/mavlink.log")),
m_enable_version_check(true),
versionMismatchIgnore(false)
{
......@@ -99,7 +99,7 @@ void MAVLinkProtocol::run()
QString MAVLinkProtocol::getLogfileName()
{
return QCoreApplication::applicationDirPath()+"/mavlink.log";
return m_logfile->fileName();
}
/**
......@@ -391,21 +391,27 @@ void MAVLinkProtocol::enableLogging(bool enabled)
{
if (enabled && !m_loggingEnabled)
{
m_logfile = new QFile(getLogfileName());
if (m_logfile->isOpen()) m_logfile->close();
m_logfile->open(QIODevice::WriteOnly | QIODevice::Append);
}
else
else if (!enabled)
{
m_logfile->close();
delete m_logfile;
m_logfile = NULL;
}
m_loggingEnabled = enabled;
emit loggingChanged(enabled);
}
void MAVLinkProtocol::setLogfileName(const QString& filename)
{
m_logfile->close();
m_logfile->setFileName(filename);
}
void MAVLinkProtocol::enableVersionCheck(bool enabled)
{
m_enable_version_check = enabled;
emit versionCheckChanged(enabled);
}
bool MAVLinkProtocol::heartbeatsEnabled(void)
......
......@@ -70,8 +70,10 @@ public:
bool loggingEnabled(void);
/** @brief Get protocol version check state */
bool versionCheckEnabled(void);
/** @brief Get the protocol version */
int getVersion() { return MAVLINK_VERSION; }
/** @brief Get the name of the packet log file */
static QString getLogfileName();
QString getLogfileName();
public slots:
/** @brief Receive bytes from a communication interface */
......@@ -89,6 +91,9 @@ public slots:
/** @brief Enable/disable binary packet logging */
void enableLogging(bool enabled);
/** @brief Set log file name */
void setLogfileName(const QString& filename);
/** @brief Enable / disable version check */
void enableVersionCheck(bool enabled);
......
......@@ -97,8 +97,8 @@ MAVLinkSimulationLink::MAVLinkSimulationLink(QString readFile, QString writeFile
LinkManager::instance()->add(this);
// Open packet log
mavlinkLogFile = new QFile(MAVLinkProtocol::getLogfileName());
mavlinkLogFile->open(QIODevice::ReadOnly);
mavlinkLogFile = new QFile();
//mavlinkLogFile->open(QIODevice::ReadOnly);
}
MAVLinkSimulationLink::~MAVLinkSimulationLink()
......@@ -141,7 +141,7 @@ void MAVLinkSimulationLink::run()
}
last = MG::TIME::getGroundTimeNow();
}
MG::SLEEP::msleep(2);
MG::SLEEP::msleep(3);
}
}
......
......@@ -108,8 +108,9 @@ void SerialLink::loadSettings()
setPortName(settings.value("SERIALLINK_COMM_PORT").toString());
setBaudRateType(settings.value("SERIALLINK_COMM_BAUD").toInt());
setParityType(settings.value("SERIALLINK_COMM_PARITY").toInt());
setStopBitsType(settings.value("SERIALLINK_COMM_STOPBITS").toInt());
setDataBitsType(settings.value("SERIALLINK_COMM_DATABITS").toInt());
setStopBits(settings.value("SERIALLINK_COMM_STOPBITS").toInt());
setDataBits(settings.value("SERIALLINK_COMM_DATABITS").toInt());
setFlowType(settings.value("SERIALLINK_COMM_FLOW_CONTROL").toInt());
}
}
......@@ -120,8 +121,9 @@ void SerialLink::writeSettings()
settings.setValue("SERIALLINK_COMM_PORT", this->porthandle);
settings.setValue("SERIALLINK_COMM_BAUD", getBaudRateType());
settings.setValue("SERIALLINK_COMM_PARITY", getParityType());
settings.setValue("SERIALLINK_COMM_STOPBITS", getStopBitsType());
settings.setValue("SERIALLINK_COMM_DATABITS", getDataBitsType());
settings.setValue("SERIALLINK_COMM_STOPBITS", getStopBits());
settings.setValue("SERIALLINK_COMM_DATABITS", getDataBits());
settings.setValue("SERIALLINK_COMM_FLOW_CONTROL", getFlowType());
settings.sync();
}
......@@ -316,10 +318,10 @@ bool SerialLink::hardwareConnect()
{
emit connected();
emit connected(true);
writeSettings();
}
writeSettings();
return connectionUp;
}
......@@ -531,6 +533,48 @@ int SerialLink::getStopBitsType()
return stopBits;
}
int SerialLink::getDataBits()
{
int ret;
switch (dataBits)
{
case DATA_5:
ret = 5;
break;
case DATA_6:
ret = 6;
break;
case DATA_7:
ret = 7;
break;
case DATA_8:
ret = 8;
break;
default:
ret = 0;
break;
}
return ret;
}
int SerialLink::getStopBits()
{
int ret;
switch (stopBits)
{
case STOP_1:
ret = 1;
break;
case STOP_2:
ret = 2;
break;
default:
ret = 0;
break;
}
return ret;
}
bool SerialLink::setPortName(QString portName)
{
if(portName.trimmed().length() > 0)
......@@ -845,8 +889,7 @@ bool SerialLink::setParityType(int parity)
}
// FIXME Works not as anticipated by user!
bool SerialLink::setDataBitsType(int dataBits)
bool SerialLink::setDataBits(int dataBits)
{
bool accepted = true;
......@@ -879,12 +922,12 @@ bool SerialLink::setDataBitsType(int dataBits)
return accepted;
}
// FIXME WORKS NOT AS ANTICIPATED BY USER!
bool SerialLink::setStopBitsType(int stopBits)
bool SerialLink::setStopBits(int stopBits)
{
bool reconnect = false;
bool accepted = true;
if(isConnected()) {
if(isConnected())
{
disconnect();
reconnect = true;
}
......@@ -907,3 +950,51 @@ bool SerialLink::setStopBitsType(int stopBits)
if(reconnect) connect();
return accepted;
}
bool SerialLink::setDataBitsType(int dataBits)
{
bool reconnect = false;
bool accepted = false;
if (isConnected())
{
disconnect();
reconnect = true;
}
if (dataBits >= (int)DATA_5 && dataBits <= (int)DATA_8)
{
DataBitsType newBits = (DataBitsType) dataBits;
port->setDataBits(newBits);
if(reconnect)
{
connect();
}
accepted = true;
}
return accepted;
}
bool SerialLink::setStopBitsType(int stopBits)
{
bool reconnect = false;
bool accepted = false;
if(isConnected())
{
disconnect();
reconnect = true;
}
if (stopBits >= (int)STOP_1 && dataBits <= (int)STOP_2)
{
StopBitsType newBits = (StopBitsType) stopBits;
port->setStopBits(newBits);
accepted = true;
}
if(reconnect) connect();
return accepted;
}
......@@ -74,6 +74,10 @@ public:
*/
QString getName();
int getBaudRate();
int getDataBits();
int getStopBits();
// ENUM values
int getBaudRateType();
int getFlowType();
int getParityType();
......@@ -103,6 +107,10 @@ public:
public slots:
bool setPortName(QString portName);
bool setBaudRate(int rate);
bool setDataBits(int dataBits);
bool setStopBits(int stopBits);
// Set ENUM values
bool setBaudRateType(int rateIndex);
bool setFlowType(int flow);
bool setParityType(int parity);
......
......@@ -43,6 +43,9 @@ class SerialLinkInterface : public LinkInterface {
public:
virtual QString getPortName() = 0;
virtual int getBaudRate() = 0;
virtual int getDataBits() = 0;
virtual int getStopBits() = 0;
virtual int getBaudRateType() = 0;
virtual int getFlowType() = 0;
virtual int getParityType() = 0;
......
......@@ -49,7 +49,7 @@ UDPLink::UDPLink(QHostAddress host, quint16 port)
// Set unique ID and add link to the list of links
this->id = getNextLinkId();
this->name = tr("UDP link ") + QString::number(getId());
this->name = tr("UDP Link (port:%1)").arg(14550);
LinkManager::instance()->add(this);
}
......
......@@ -663,12 +663,12 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
mavlink_nav_filter_bias_t bias;
mavlink_msg_nav_filter_bias_decode(&message, &bias);
quint64 time = MG::TIME::getGroundTimeNow();
emit valueChanged(uasId, "b_f[0]", bias.accel_0, time);
emit valueChanged(uasId, "b_f[1]", bias.accel_1, time);
emit valueChanged(uasId, "b_f[2]", bias.accel_2, time);
emit valueChanged(uasId, "b_w[0]", bias.gyro_0, time);
emit valueChanged(uasId, "b_w[1]", bias.gyro_1, time);
emit valueChanged(uasId, "b_w[2]", bias.gyro_2, time);
emit valueChanged(uasId, "b_f[0]", "raw", bias.accel_0, time);
emit valueChanged(uasId, "b_f[1]", "raw", bias.accel_1, time);
emit valueChanged(uasId, "b_f[2]", "raw", bias.accel_2, time);
emit valueChanged(uasId, "b_w[0]", "raw", bias.gyro_0, time);
emit valueChanged(uasId, "b_w[1]", "raw", bias.gyro_1, time);
emit valueChanged(uasId, "b_w[2]", "raw", bias.gyro_2, time);
}
break;
case MAVLINK_MSG_ID_RADIO_CALIBRATION:
......
......@@ -55,6 +55,7 @@ void UASWaypointManager::timeout()
{
protocol_timer.start(PROTOCOL_TIMEOUT_MS);
current_retries--;
emit updateStatusString(tr("Timeout, retrying (retries left: %1)").arg(current_retries));
qDebug() << "Timeout, retrying (retries left:" << current_retries << ")";
if (current_state == WP_GETLIST)
{
......@@ -517,7 +518,7 @@ void UASWaypointManager::sendWaypointClearAll()
wpca.target_system = uas.getUASID();
wpca.target_component = MAV_COMP_ID_WAYPOINTPLANNER;
emit updateStatusString(QString("clearing waypoint list..."));
emit updateStatusString(QString("Clearing waypoint list..."));
mavlink_msg_waypoint_clear_all_encode(uas.mavlink->getSystemId(), uas.mavlink->getComponentId(), &message, &wpca);
uas.sendMessage(message);
......@@ -554,7 +555,7 @@ void UASWaypointManager::sendWaypointCount()
wpc.count = current_count;
qDebug() << "sent waypoint count (" << wpc.count << ") to ID " << wpc.target_system;
emit updateStatusString(QString("start transmitting waypoints..."));
emit updateStatusString(QString("Starting to transmit waypoints..."));
mavlink_msg_waypoint_count_encode(uas.mavlink->getSystemId(), uas.mavlink->getComponentId(), &message, &wpc);
uas.sendMessage(message);
......@@ -571,7 +572,7 @@ void UASWaypointManager::sendWaypointRequestList()
wprl.target_system = uas.getUASID();
wprl.target_component = MAV_COMP_ID_WAYPOINTPLANNER;
emit updateStatusString(QString("requesting waypoint list..."));
emit updateStatusString(QString("Requesting waypoint list..."));
mavlink_msg_waypoint_request_list_encode(uas.mavlink->getSystemId(), uas.mavlink->getComponentId(), &message, &wprl);
uas.sendMessage(message);
......@@ -591,7 +592,7 @@ void UASWaypointManager::sendWaypointRequest(quint16 seq)
wpr.target_component = MAV_COMP_ID_WAYPOINTPLANNER;
wpr.seq = seq;
emit updateStatusString(QString("retrieving waypoint ID %1 of %2 total").arg(wpr.seq).arg(current_count));
emit updateStatusString(QString("Retrieving waypoint ID %1 of %2 total").arg(wpr.seq).arg(current_count));
mavlink_msg_waypoint_request_encode(uas.mavlink->getSystemId(), uas.mavlink->getComponentId(), &message, &wpr);
uas.sendMessage(message);
......@@ -612,7 +613,7 @@ void UASWaypointManager::sendWaypoint(quint16 seq)
wp->target_system = uas.getUASID();
wp->target_component = MAV_COMP_ID_WAYPOINTPLANNER;
emit updateStatusString(QString("sending waypoint ID %1 of %2 total").arg(wp->seq).arg(current_count));
emit updateStatusString(QString("Sending waypoint ID %1 of %2 total").arg(wp->seq).arg(current_count));
mavlink_msg_waypoint_encode(uas.mavlink->getSystemId(), uas.mavlink->getComponentId(), &message, wp);
uas.sendMessage(message);
......
......@@ -106,7 +106,7 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn
QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, ui.linkGroupBox);
layout->addWidget(conf);
ui.linkGroupBox->setLayout(layout);
ui.linkGroupBox->setTitle(tr("serial link"));
ui.linkGroupBox->setTitle(tr("Serial Link"));
//ui.linkGroupBox->setTitle(link->getName());
//connect(link, SIGNAL(nameChanged(QString)), ui.linkGroupBox, SLOT(setTitle(QString)));
}
......@@ -142,13 +142,13 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn
// Open details pane for MAVLink if necessary
MAVLinkProtocol* mavlink = dynamic_cast<MAVLinkProtocol*>(protocol);
if(mavlink != 0)
if (mavlink != 0)
{
QWidget* conf = new MAVLinkSettingsWidget(mavlink, this);
QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, ui.protocolGroupBox);
layout->addWidget(conf);
ui.protocolGroupBox->setLayout(layout);
ui.protocolGroupBox->setTitle(protocol->getName());
ui.protocolGroupBox->setTitle(protocol->getName()+" (Global Settings)");
}
else
{
......
......@@ -105,6 +105,8 @@ DebugConsole::DebugConsole(QWidget *parent) :
connect(m_ui->holdButton, SIGNAL(toggled(bool)), this, SLOT(hold(bool)));
// Connect connect button
connect(m_ui->connectButton, SIGNAL(clicked()), this, SLOT(handleConnectButton()));
// Connect the special chars combo box
connect(m_ui->specialComboBox, SIGNAL(activated(QString)), this, SLOT(appendSpecialSymbol(QString)));
this->setVisible(false);
}
......@@ -327,8 +329,78 @@ void DebugConsole::receiveBytes(LinkInterface* link, QByteArray bytes)
}
}
QByteArray DebugConsole::symbolNameToBytes(const QString& text)
{
QByteArray b;
if (text == "LF")
{
b.append(static_cast<char>(0x0A));
}
else if (text == "FF")
{
b.append(static_cast<char>(0x0C));
}
else if (text == "CR")
{
b.append(static_cast<char>(0x0D));
}
else if (text == "CR+LF")
{
b.append(static_cast<char>(0x0D));
b.append(static_cast<char>(0x0A));
}
else if (text == "TAB")
{
b.append(static_cast<char>(0x09));
}
else if (text == "NUL")
{
b.append(static_cast<char>(0x00));
}
else if (text == "ESC")
{
b.append(static_cast<char>(0x1B));
}
else if (text == "~")
{
b.append(static_cast<char>(0x7E));
}
else if (text == "<Space>")
{
b.append(static_cast<char>(0x20));
}
return b;
}
void DebugConsole::appendSpecialSymbol(const QString& text)
{
QString line = m_ui->sendText->text();
QByteArray symbols = symbolNameToBytes(text);
// The text is appended to the enter field
if (convertToAscii)
{
line.append(symbols);
}
else
{
for (int i = 0; i < symbols.size(); i++)
{
QString add(" 0x%1");
line.append(add.arg(static_cast<char>(symbols.at(i)), 2, 16, QChar('0')));
}
}
m_ui->sendText->setText(line);
}
void DebugConsole::sendBytes()
{
if (!currLink->isConnected())
{
m_ui->sentText->setText(tr("Nothing sent. The link %1 is unconnected. Please connect first.").arg(currLink->getName()));
return;
}
QByteArray transmit;
QString feedback;
bool ok = true;
......@@ -382,8 +454,16 @@ void DebugConsole::sendBytes()
if (ok && m_ui->sendText->text().toLatin1().size() > 0)
{
// Transmit only if conversion succeeded
currLink->writeBytes(transmit, transmit.size());
m_ui->sentText->setText(tr("Sent: ") + feedback);
// int transmitted =
currLink->writeBytes(transmit, transmit.size());
// if (transmit.size() == transmitted)
// {
m_ui->sentText->setText(tr("Sent: ") + feedback);
// }
// else
// {
// m_ui->sentText->setText(tr("Error during sending: Transmitted only %1 bytes instead of %2.").arg(transmitted, transmit.size()));
// }
}
else if (m_ui->sendText->text().toLatin1().size() > 0)
{
......@@ -403,6 +483,8 @@ void DebugConsole::hexModeEnabled(bool mode)
{
convertToAscii = !mode;
m_ui->receiveText->clear();
m_ui->sendText->clear();
m_ui->sentText->clear();
}
/**
......
......@@ -83,6 +83,8 @@ public slots:
void setAutoHold(bool hold);
/** @brief Receive plain text message to output to the user */
void receiveTextMessage(int id, int component, int severity, QString text);
/** @brief Append a special symbol */
void appendSpecialSymbol(const QString& text);
protected slots:
/** @brief Draw information overlay */
......@@ -92,6 +94,7 @@ public slots:
protected:
void changeEvent(QEvent *e);
QByteArray symbolNameToBytes(const QString& symbol);
QList<LinkInterface*> links;
LinkInterface* currLink;
......
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>463</width>
<height>159</height>
<width>447</width>
<height>181</height>
</rect>
</property>
<property name="windowTitle">
......@@ -106,24 +106,74 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLineEdit" name="sendText">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Type the bytes to send here, use 0xAA format for HEX (Check HEX checkbox above)</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="10,10,10,0">
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,10,10,10,0">
<property name="spacing">
<number>5</number>
</property>
<item>
<widget class="QComboBox" name="specialComboBox">
<property name="maxVisibleItems">
<number>10</number>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContentsOnFirstShow</enum>
</property>
<property name="minimumContentsLength">
<number>1</number>
</property>
<item>
<property name="text">
<string>Add..</string>
</property>
</item>
<item>
<property name="text">
<string>CR+LF</string>
</property>
</item>
<item>
<property name="text">
<string>LF</string>
</property>
</item>
<item>
<property name="text">
<string>FF</string>
</property>
</item>
<item>
<property name="text">
<string>CR</string>
</property>
</item>
<item>
<property name="text">
<string>TAB</string>
</property>
</item>
<item>
<property name="text">
<string>NUL</string>
</property>
</item>
<item>
<property name="text">
<string>ESC</string>
</property>
</item>
<item>
<property name="text">
<string>~</string>
</property>
</item>
<item>
<property name="text">
<string>&lt;Space&gt;</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QPushButton" name="transmitButton">
<property name="toolTip">
......@@ -164,6 +214,19 @@
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLineEdit" name="sendText">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Type the bytes to send here, use 0xAA format for HEX (Check HEX checkbox above)</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
......
......@@ -812,6 +812,7 @@ float HDDisplay::refLineWidthToPen(float line)
void HDDisplay::updateValue(const int uasId, const QString& name, const QString& unit, const double value, const quint64 msec)
{
Q_UNUSED(uasId);
Q_UNUSED(unit);
// Update mean
const float oldMean = valuesMean.value(name, 0.0f);
const int meanCount = valuesCount.value(name, 0);
......
......@@ -27,6 +27,11 @@ This file is part of the QGROUNDCONTROL project
* @author Lorenz Meier <mail@qgroundcontrol.org>
*/
#include <QFileInfo>
#include <QFileDialog>
#include <QMessageBox>
#include <QDesktopServices>
#include "MAVLinkSettingsWidget.h"
#include "ui_MAVLinkSettingsWidget.h"
......@@ -37,6 +42,8 @@ MAVLinkSettingsWidget::MAVLinkSettingsWidget(MAVLinkProtocol* protocol, QWidget
{
m_ui->setupUi(this);
m_ui->gridLayout->setAlignment(Qt::AlignTop);
// Initialize state
m_ui->heartbeatCheckBox->setChecked(protocol->heartbeatsEnabled());
m_ui->loggingCheckBox->setChecked(protocol->loggingEnabled());
......@@ -49,7 +56,59 @@ MAVLinkSettingsWidget::MAVLinkSettingsWidget(MAVLinkProtocol* protocol, QWidget
connect(m_ui->loggingCheckBox, SIGNAL(toggled(bool)), protocol, SLOT(enableLogging(bool)));
connect(protocol, SIGNAL(versionCheckChanged(bool)), m_ui->versionCheckBox, SLOT(setChecked(bool)));
connect(m_ui->versionCheckBox, SIGNAL(toggled(bool)), protocol, SLOT(enableVersionCheck(bool)));
connect(m_ui->logFileButton, SIGNAL(clicked()), this, SLOT(chooseLogfileName()));
// Update values
m_ui->versionLabel->setText(tr("MAVLINK_VERSION: %1").arg(protocol->getVersion()));
updateLogfileName(protocol->getLogfileName());
// Connect visibility updates
connect(protocol, SIGNAL(versionCheckChanged(bool)), m_ui->versionLabel, SLOT(setVisible(bool)));
m_ui->versionLabel->setVisible(protocol->versionCheckEnabled());
//connect(m_ui->versionCheckBox, SIGNAL(toggled(bool)), m_ui->versionSpacer, SLOT(setVisible(bool)));
//connect(m_ui->loggingCheckBox, SIGNAL(toggled(bool)), m_ui->logFileSpacer, SLOT(setVisible(bool)));
connect(protocol, SIGNAL(loggingChanged(bool)), m_ui->logFileLabel, SLOT(setVisible(bool)));
m_ui->logFileLabel->setVisible(protocol->loggingEnabled());
connect(protocol, SIGNAL(loggingChanged(bool)), m_ui->logFileButton, SLOT(setVisible(bool)));
m_ui->logFileButton->setVisible(protocol->loggingEnabled());
// Update settings
m_ui->loggingCheckBox->setChecked(protocol->loggingEnabled());
m_ui->heartbeatCheckBox->setChecked(protocol->heartbeatsEnabled());
m_ui->versionCheckBox->setChecked(protocol->versionCheckEnabled());
}
void MAVLinkSettingsWidget::updateLogfileName(const QString& fileName)
{
QFileInfo file(fileName);
m_ui->logFileLabel->setText(file.fileName());
}
void MAVLinkSettingsWidget::chooseLogfileName()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Specify MAVLink log file name"), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), tr("MAVLink Logfile (*.mavlink);;"));
if (!fileName.endsWith(".mavlink"))
{
fileName.append(".mavlink");
}
QFileInfo file(fileName);
if (file.exists() && !file.isWritable())
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(tr("The selected logfile is not writable"));
msgBox.setInformativeText(tr("Please make sure that the file %1 is writable or select a different file").arg(fileName));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
else
{
updateLogfileName(fileName);
protocol->setLogfileName(fileName);
}
}
MAVLinkSettingsWidget::~MAVLinkSettingsWidget()
......
......@@ -15,6 +15,12 @@ public:
MAVLinkSettingsWidget(MAVLinkProtocol* protocol, QWidget *parent = 0);
~MAVLinkSettingsWidget();
public slots:
/** @brief Update the log file name display */
void updateLogfileName(const QString& fileName);
/** @brief Start the file select dialog for the log file */
void chooseLogfileName();
protected:
MAVLinkProtocol* protocol;
void changeEvent(QEvent *e);
......
......@@ -6,51 +6,85 @@
<rect>
<x>0</x>
<y>0</y>
<width>267</width>
<height>123</height>
<width>361</width>
<height>145</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>6</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout" columnstretch="1,100,1">
<item row="0" column="0" colspan="3">
<widget class="QCheckBox" name="heartbeatCheckBox">
<property name="text">
<string>Emit heartbeat</string>
</property>
</widget>
</item>
<item>
<item row="1" column="0" colspan="3">
<widget class="QCheckBox" name="loggingCheckBox">
<property name="text">
<string>Log all MAVLink packets</string>
</property>
</widget>
</item>
<item>
<item row="3" column="0">
<spacer name="logFileSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>8</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0" colspan="3">
<widget class="QCheckBox" name="versionCheckBox">
<property name="text">
<string>Only accept MAVs with same protocol version</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<item row="5" column="0">
<spacer name="versionSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>84</height>
<width>8</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="1" colspan="2">
<widget class="QLabel" name="versionLabel">
<property name="text">
<string>MAVLINK_VERSION: </string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="logFileLabel">
<property name="text">
<string>Logfile name</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="logFileButton">
<property name="text">
<string>Select..</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
......
This diff is collapsed.
......@@ -104,6 +104,9 @@ public slots:
void addLink();
void addLink(LinkInterface* link);
void configure();
/** @brief Set the currently controlled UAS */
void setActiveUAS(UASInterface* uas);
/** @brief Add a new UAS */
void UASCreated(UASInterface* uas);
void startVideoCapture();
void stopVideoCapture();
......@@ -208,6 +211,7 @@ protected:
MENU_SLUGS_PID,
MENU_SLUGS_HIL,
MENU_SLUGS_CAMERA,
MENU_MAVLINK_LOG_PLAYER,
CENTRAL_SEPARATOR= 255, // do not change
CENTRAL_LINECHART,
CENTRAL_PROTOCOL,
......@@ -297,6 +301,7 @@ protected:
/** @brief Keeps track of the current view */
VIEW_SECTIONS currentView;
bool aboutToCloseFlag;
bool changingViewsFlag;
void clearView();
......@@ -360,6 +365,7 @@ protected:
QPointer<QDockWidget> watchdogControlDockWidget;
QPointer<QDockWidget> headUpDockWidget;
QPointer<QDockWidget> logPlayerDockWidget;
QPointer<QDockWidget> hsiDockWidget;
QPointer<QDockWidget> rcViewDockWidget;
......
......@@ -49,23 +49,30 @@
<addaction name="actionNewCustomWidget"/>
<addaction name="actionMuteAudioOutput"/>
<addaction name="actionSimulate"/>
<addaction name="actionPreferences"/>
<addaction name="separator"/>
<addaction name="actionReloadStyle"/>
<addaction name="actionExit"/>
</widget>
<widget class="QMenu" name="menuNetwork">
<property name="title">
<string>Network</string>
<string>Communication</string>
</property>
<addaction name="actionAdd_Link"/>
<addaction name="separator"/>
</widget>
<widget class="QMenu" name="menuConnected_Systems">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Select System</string>
</property>
</widget>
<widget class="QMenu" name="menuUnmanned_System">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Unmanned System</string>
</property>
......@@ -76,8 +83,6 @@
<addaction name="actionLand"/>
<addaction name="actionEmergency_Land"/>
<addaction name="actionEmergency_Kill"/>
<addaction name="separator"/>
<addaction name="actionConfiguration"/>
</widget>
<widget class="QMenu" name="menuTools">
<property name="title">
......@@ -124,6 +129,9 @@
</property>
</action>
<action name="actionLiftoff">
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../../mavground.qrc">
<normaloff>:/images/control/launch.svg</normaloff>
......@@ -143,6 +151,10 @@
</property>
</action>
<action name="actionEmergency_Land">
<property name="icon">
<iconset resource="../../mavground.qrc">
<normaloff>:/images/actions/process-stop.svg</normaloff>:/images/actions/process-stop.svg</iconset>
</property>
<property name="text">
<string>Emergency Land</string>
</property>
......@@ -151,6 +163,10 @@
</property>
</action>
<action name="actionEmergency_Kill">
<property name="icon">
<iconset resource="../../mavground.qrc">
<normaloff>:/images/actions/process-stop.svg</normaloff>:/images/actions/process-stop.svg</iconset>
</property>
<property name="text">
<string>Kill UAS</string>
</property>
......@@ -312,6 +328,10 @@
</property>
</action>
<action name="actionNewCustomWidget">
<property name="icon">
<iconset resource="../../mavground.qrc">
<normaloff>:/images/apps/utilities-system-monitor.svg</normaloff>:/images/apps/utilities-system-monitor.svg</iconset>
</property>
<property name="text">
<string>New Custom Widget</string>
</property>
......@@ -332,6 +352,18 @@
<string>Mute Audio Output</string>
</property>
</action>
<action name="actionPreferences">
<property name="icon">
<iconset resource="../../mavground.qrc">
<normaloff>:/images/categories/preferences-system.svg</normaloff>:/images/categories/preferences-system.svg</iconset>
</property>
<property name="text">
<string>Preferences</string>
</property>
<property name="toolTip">
<string>QGroundControl global settings</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
......
#include <QFileDialog>
#include <QMessageBox>
#include <QDesktopServices>
#include "QGCMAVLinkLogPlayer.h"
#include "ui_QGCMAVLinkLogPlayer.h"
QGCMAVLinkLogPlayer::QGCMAVLinkLogPlayer(MAVLinkProtocol* mavlink, QWidget *parent) :
QWidget(parent),
lineCounter(0),
totalLines(0),
startTime(0),
endTime(0),
currentTime(0),
mavlink(mavlink),
ui(new Ui::QGCMAVLinkLogPlayer)
{
ui->setupUi(this);
ui->gridLayout->setAlignment(Qt::AlignTop);
// Setup buttons
connect(ui->selectFileButton, SIGNAL(clicked()), this, SLOT(selectLogFile()));
connect(ui->pauseButton, SIGNAL(clicked()), this, SLOT(pause()));
connect(ui->playButton, SIGNAL(clicked()), this, SLOT(play()));
}
QGCMAVLinkLogPlayer::~QGCMAVLinkLogPlayer()
{
delete ui;
}
void QGCMAVLinkLogPlayer::play()
{
if (logFile.isOpen())
{
ui->pauseButton->setChecked(false);
}
else
{
ui->playButton->setChecked(false);
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Information);
msgBox.setText(tr("No logfile selected"));
msgBox.setInformativeText(tr("Please select first a MAVLink log file before playing it."));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
}
void QGCMAVLinkLogPlayer::pause()
{
ui->playButton->setChecked(false);
}
void QGCMAVLinkLogPlayer::selectLogFile()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Specify MAVLink log file name"), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), tr("MAVLink Logfile (*.mavlink);;"));
loadLogFile(fileName);
}
void QGCMAVLinkLogPlayer::loadLogFile(const QString& file)
{
logFile.setFileName(file);
if (!logFile.open(QFile::ReadOnly))
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(tr("The selected logfile is unreadable"));
msgBox.setInformativeText(tr("Please make sure that the file %1 is readable or select a different file").arg(file));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
logFile.setFileName("");
}
else
{
ui->logFileNameLabel->setText(tr("%1").arg(file));
}
}
/**
* This function is the "mainloop" of the log player, reading one line
* and adjusting the mainloop timer to read the next line in time.
* It might not perfectly match the timing of the log file,
* but it will never induce a static drift into the log file replay.
* For scientific logging, the use of onboard timestamps and the log
* functionality of the line chart plot is recommended.
*/
void QGCMAVLinkLogPlayer::readLine()
{
// Ui update: Only every 20 messages
// to prevent flickering and high CPU load
// Update status label
// Update progress bar
}
void QGCMAVLinkLogPlayer::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
#ifndef QGCMAVLINKLOGPLAYER_H
#define QGCMAVLINKLOGPLAYER_H
#include <QWidget>
#include <QFile>
#include "MAVLinkProtocol.h"
namespace Ui {
class QGCMAVLinkLogPlayer;
}
/**
* @brief Replays MAVLink log files
*
* This class allows to replay MAVLink logs at varying speeds.
* captured flights can be replayed, shown to others and analyzed
* in-depth later on.
*/
class QGCMAVLinkLogPlayer : public QWidget
{
Q_OBJECT
public:
explicit QGCMAVLinkLogPlayer(MAVLinkProtocol* mavlink, QWidget *parent = 0);
~QGCMAVLinkLogPlayer();
public slots:
/** @brief Replay the logfile */
void play();
/** @brief Pause the logfile */
void pause();
/** @brief Select logfile */
void selectLogFile();
/** @brief Load log file */
void loadLogFile(const QString& file);
protected:
int lineCounter;
int totalLines;
quint64 startTime;
quint64 endTime;
quint64 currentTime;
MAVLinkProtocol* mavlink;
QFile logFile;
QTimer loopTimer;
void changeEvent(QEvent *e);
void readLine();
private:
Ui::QGCMAVLinkLogPlayer *ui;
};
#endif // QGCMAVLINKLOGPLAYER_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QGCMAVLinkLogPlayer</class>
<widget class="QWidget" name="QGCMAVLinkLogPlayer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>407</width>
<height>144</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="1,10,10,1,1,0">
<property name="horizontalSpacing">
<number>12</number>
</property>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="logFileNameLabel">
<property name="text">
<string>Please choose logfile</string>
</property>
</widget>
</item>
<item row="0" column="3" colspan="3">
<widget class="QPushButton" name="selectFileButton">
<property name="text">
<string>Select File</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="5">
<widget class="QSlider" name="speedSlider">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="sliderPosition">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QLabel" name="logStatsLabel">
<property name="text">
<string>No logfile selected..</string>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="QToolButton" name="pauseButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../mavground.qrc">
<normaloff>:/images/actions/media-playback-pause.svg</normaloff>:/images/actions/media-playback-pause.svg</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0" colspan="6">
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="speedLabel">
<property name="text">
<string>Speed</string>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QToolButton" name="playButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../mavground.qrc">
<normaloff>:/images/actions/media-playback-start.svg</normaloff>:/images/actions/media-playback-start.svg</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../mavground.qrc"/>
</resources>
<connections/>
</ui>
......@@ -239,12 +239,17 @@ userConfigured(false)
// Setup the user interface according to link type
ui.setupUi(this);
//this->setVisible(false);
//this->hide();
// Create action to open this menu
// Create configuration action for this link
// Connect the current UAS
action = new QAction(QIcon(":/images/devices/network-wireless.svg"), "", link);
setLinkName(link->getName());
setupPortList();
connect(action, SIGNAL(triggered()), this, SLOT(configureCommunication()));
// Make sure that a change in the link name will be reflected in the UI
......@@ -258,10 +263,8 @@ userConfigured(false)
connect(ui.parNone, SIGNAL(toggled(bool)), this, SLOT(setParityNone()));
connect(ui.parOdd, SIGNAL(toggled(bool)), this, SLOT(setParityOdd()));
connect(ui.parEven, SIGNAL(toggled(bool)), this, SLOT(setParityEven()));
connect(ui.dataBitsSpinBox, SIGNAL(valueChanged(int)), this->link, SLOT(setDataBitsType(int)));
connect(ui.stopBitsSpinBox, SIGNAL(valueChanged(int)), this->link, SLOT(setStopBitsType(int)));
setupPortList();
connect(ui.dataBitsSpinBox, SIGNAL(valueChanged(int)), this->link, SLOT(setDataBits(int)));
connect(ui.stopBitsSpinBox, SIGNAL(valueChanged(int)), this->link, SLOT(setStopBits(int)));
//connect(this->link, SIGNAL(connected(bool)), this, SLOT());
ui.portName->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow);
......@@ -299,8 +302,8 @@ userConfigured(false)
ui.baudRate->setCurrentIndex(this->link->getBaudRateType());
ui.dataBitsSpinBox->setValue(this->link->getDataBitsType() + 5);
ui.stopBitsSpinBox->setValue(this->link->getStopBitsType() + 1);
ui.dataBitsSpinBox->setValue(this->link->getDataBits());
ui.stopBitsSpinBox->setValue(this->link->getStopBits());
portCheckTimer = new QTimer(this);
portCheckTimer->setInterval(1000);
......@@ -308,7 +311,7 @@ userConfigured(false)
// Display the widget
this->window()->setWindowTitle(tr("Serial Communication Settings"));
this->show();
//this->show();
}
else
{
......@@ -323,18 +326,14 @@ SerialConfigurationWindow::~SerialConfigurationWindow() {
void SerialConfigurationWindow::showEvent(QShowEvent* event)
{
if (event->isAccepted())
{
portCheckTimer->start();
}
Q_UNUSED(event);
portCheckTimer->start();
}
void SerialConfigurationWindow::hideEvent(QHideEvent* event)
{
if (event->isAccepted())
{
portCheckTimer->stop();
}
Q_UNUSED(event);
portCheckTimer->stop();
}
QAction* SerialConfigurationWindow::getAction()
......
......@@ -119,8 +119,7 @@ updateTimer(new QTimer())
curvesWidgetLayout->addWidget(value, labelRow, 3);
// Unit
label->setText("Unit");
curvesWidgetLayout->addWidget(new QLabel(tr("Unit")), labelRow, 4);
//curvesWidgetLayout->addWidget(new QLabel(tr("Unit")), labelRow, 4);
// Mean
mean = new QLabel(this);
......@@ -216,9 +215,8 @@ void LinechartWidget::createLayout()
connect(logButton, SIGNAL(clicked()), this, SLOT(startLogging()));
// Ground time button
QToolButton* timeButton = new QToolButton(this);
QCheckBox* timeButton = new QCheckBox(this);
timeButton->setText(tr("Ground Time"));
timeButton->setCheckable(true);
timeButton->setToolTip(tr("Overwrite timestamp of data from vehicle with ground receive time. Helps if the plots are not visible because of missing or invalid onboard time."));
timeButton->setWhatsThis(tr("Overwrite timestamp of data from vehicle with ground receive time. Helps if the plots are not visible because of missing or invalid onboard time."));
bool gTimeDefault = true;
......@@ -228,6 +226,13 @@ void LinechartWidget::createLayout()
layout->setColumnStretch(4, 0);
connect(timeButton, SIGNAL(clicked(bool)), activePlot, SLOT(enforceGroundTime(bool)));
unitsCheckBox = new QCheckBox(this);
unitsCheckBox->setText(tr("Show units"));
unitsCheckBox->setChecked(true);
unitsCheckBox->setToolTip(tr("Enable unit display in curve list"));
unitsCheckBox->setWhatsThis(tr("Enable unit display in curve list"));
layout->addWidget(unitsCheckBox, 1, 5);
// Create the scroll bar
//scrollbar = new QScrollBar(Qt::Horizontal, ui.diagramGroupBox);
//scrollbar->setMinimum(MIN_TIME_SCROLLBAR_VALUE);
......@@ -241,7 +246,7 @@ void LinechartWidget::createLayout()
// Add scroll bar to layout and make sure it gets all available space
//layout->addWidget(scrollbar, 1, 5);
layout->setColumnStretch(5, 10);
//layout->setColumnStretch(5, 10);
ui.diagramGroupBox->setLayout(layout);
......@@ -254,8 +259,8 @@ void LinechartWidget::createLayout()
// FIXME
// Connect notifications from the plot to the user interface
connect(activePlot, SIGNAL(curveAdded(QString)), this, SLOT(addCurve(QString)));
connect(activePlot, SIGNAL(curveRemoved(QString)), this, SLOT(removeCurve(QString)));
//connect(activePlot, SIGNAL(curveAdded(QString)), this, SLOT(addCurve(QString)));
//connect(activePlot, SIGNAL(curveRemoved(QString)), this, SLOT(removeCurve(QString)));
// Scrollbar
......@@ -313,7 +318,7 @@ void LinechartWidget::appendData(int uasId, const QString& curve, const QString&
// Make sure the curve will be created if it does not yet exist
if(!label)
{
qDebug() << "ADDING CURVE IN APPENDDATE DOUBLE";
//qDebug() << "ADDING CURVE IN APPENDDATE DOUBLE";
addCurve(curve, unit);
}
}
......@@ -594,8 +599,8 @@ void LinechartWidget::addCurve(const QString& curve, const QString& unit)
value = new QLabel(this);
value->setNum(0.00);
value->setStyleSheet(QString("QLabel {font-family:\"Courier\"; font-weight: bold;}"));
value->setToolTip(tr("Current value of ") + curve);
value->setWhatsThis(tr("Current value of ") + curve);
value->setToolTip(tr("Current value of %1 in %2 units").arg(curve, unit));
value->setWhatsThis(tr("Current value of %1 in %2 units").arg(curve, unit));
curveLabels->insert(curve+unit, value);
curvesWidgetLayout->addWidget(value, labelRow, 3);
......@@ -603,17 +608,18 @@ void LinechartWidget::addCurve(const QString& curve, const QString& unit)
unitLabel = new QLabel(this);
unitLabel->setText(unit);
unitLabel->setStyleSheet(QString("QLabel {color: %1;}").arg("#AAAAAA"));
qDebug() << "UNIT" << unit;
//qDebug() << "UNIT" << unit;
unitLabel->setToolTip(tr("Unit of ") + curve);
unitLabel->setWhatsThis(tr("Unit of ") + curve);
curvesWidgetLayout->addWidget(unitLabel, labelRow, 4);
connect(unitsCheckBox, SIGNAL(clicked(bool)), unitLabel, SLOT(setVisible(bool)));
// Mean
mean = new QLabel(this);
mean->setNum(0.00);
mean->setStyleSheet(QString("QLabel {font-family:\"Courier\"; font-weight: bold;}"));
mean->setToolTip(tr("Arithmetic mean of ") + curve);
mean->setWhatsThis(tr("Arithmetic mean of ") + curve);
mean->setToolTip(tr("Arithmetic mean of %1 in %2 units").arg(curve, unit));
mean->setWhatsThis(tr("Arithmetic mean of %1 in %2 units").arg(curve, unit));
curveMeans->insert(curve+unit, mean);
curvesWidgetLayout->addWidget(mean, labelRow, 5);
......@@ -627,8 +633,8 @@ void LinechartWidget::addCurve(const QString& curve, const QString& unit)
variance = new QLabel(this);
variance->setNum(0.00);
variance->setStyleSheet(QString("QLabel {font-family:\"Courier\"; font-weight: bold;}"));
variance->setToolTip(tr("Variance of ") + curve);
variance->setWhatsThis(tr("Variance of ") + curve);
variance->setToolTip(tr("Variance of %1 in (%2)^2 units").arg(curve, unit));
variance->setWhatsThis(tr("Variance of %1 in (%2)^2 units").arg(curve, unit));
curveVariances->insert(curve+unit, variance);
curvesWidgetLayout->addWidget(variance, labelRow, 6);
......
......@@ -132,6 +132,7 @@ protected:
QToolButton* scalingLinearButton;
QToolButton* scalingLogButton;
QToolButton* logButton;
QPointer<QCheckBox> unitsCheckBox;
QFile* logFile;
unsigned int logindex;
......
......@@ -84,6 +84,8 @@ engineOn(false)
connect(ui.setModeButton, SIGNAL(clicked()), this, SLOT(transmitMode()));
ui.modeComboBox->setCurrentIndex(0);
ui.gridLayout->setAlignment(Qt::AlignTop);
}
void UASControlWidget::setUAS(UASInterface* uas)
......
......@@ -52,6 +52,7 @@ UASListWidget::UASListWidget(QWidget *parent) : QWidget(parent), m_ui(new Ui::UA
listLayout = new QVBoxLayout(this);
listLayout->setAlignment(Qt::AlignTop);
this->setLayout(listLayout);
setObjectName("UNMANNED_SYSTEMS_LIST");
// Construct initial widget
uWidget = new QGCUnconnectedInfoWidget(this);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment