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 \ ...@@ -153,7 +153,8 @@ FORMS += src/ui/MainWindow.ui \
src/ui/uas/QGCUnconnectedInfoWidget.ui \ src/ui/uas/QGCUnconnectedInfoWidget.ui \
src/ui/designer/QGCToolWidget.ui \ src/ui/designer/QGCToolWidget.ui \
src/ui/designer/QGCParamSlider.ui \ src/ui/designer/QGCParamSlider.ui \
src/ui/designer/QGCActionButton.ui src/ui/designer/QGCActionButton.ui \
src/ui/QGCMAVLinkLogPlayer.ui
INCLUDEPATH += src \ INCLUDEPATH += src \
src/ui \ src/ui \
...@@ -259,7 +260,8 @@ HEADERS += src/MG.h \ ...@@ -259,7 +260,8 @@ HEADERS += src/MG.h \
src/ui/designer/QGCToolWidget.h \ src/ui/designer/QGCToolWidget.h \
src/ui/designer/QGCParamSlider.h \ src/ui/designer/QGCParamSlider.h \
src/ui/designer/QGCActionButton.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 # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler
macx|win32-msvc2008: { macx|win32-msvc2008: {
...@@ -380,7 +382,8 @@ SOURCES += src/main.cc \ ...@@ -380,7 +382,8 @@ SOURCES += src/main.cc \
src/ui/designer/QGCToolWidget.cc \ src/ui/designer/QGCToolWidget.cc \
src/ui/designer/QGCParamSlider.cc \ src/ui/designer/QGCParamSlider.cc \
src/ui/designer/QGCActionButton.cc \ src/ui/designer/QGCActionButton.cc \
src/ui/designer/QGCToolWidgetItem.cc src/ui/designer/QGCToolWidgetItem.cc \
src/ui/QGCMAVLinkLogPlayer.cc
macx|win32-msvc2008: { macx|win32-msvc2008: {
SOURCES += src/ui/map3D/QGCGoogleEarthView.cc SOURCES += src/ui/map3D/QGCGoogleEarthView.cc
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <QDateTime> #include <QDateTime>
#include <QColor> #include <QColor>
#include <QThread>
namespace QGC namespace QGC
{ {
...@@ -20,6 +21,36 @@ namespace QGC ...@@ -20,6 +21,36 @@ namespace QGC
const QString APPNAME = "QGROUNDCONTROL"; const QString APPNAME = "QGROUNDCONTROL";
const QString COMPANYNAME = "OPENMAV"; const QString COMPANYNAME = "OPENMAV";
const int APPLICATIONVERSION = 80; // 0.8.0 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 #define QGC_EVENTLOOP_DEBUG 0
......
...@@ -59,7 +59,7 @@ MAVLinkProtocol::MAVLinkProtocol() : ...@@ -59,7 +59,7 @@ MAVLinkProtocol::MAVLinkProtocol() :
heartbeatRate(MAVLINK_HEARTBEAT_DEFAULT_RATE), heartbeatRate(MAVLINK_HEARTBEAT_DEFAULT_RATE),
m_heartbeatsEnabled(false), m_heartbeatsEnabled(false),
m_loggingEnabled(false), m_loggingEnabled(false),
m_logfile(NULL), m_logfile(new QFile(QCoreApplication::applicationDirPath()+"/mavlink.log")),
m_enable_version_check(true), m_enable_version_check(true),
versionMismatchIgnore(false) versionMismatchIgnore(false)
{ {
...@@ -99,7 +99,7 @@ void MAVLinkProtocol::run() ...@@ -99,7 +99,7 @@ void MAVLinkProtocol::run()
QString MAVLinkProtocol::getLogfileName() QString MAVLinkProtocol::getLogfileName()
{ {
return QCoreApplication::applicationDirPath()+"/mavlink.log"; return m_logfile->fileName();
} }
/** /**
...@@ -391,21 +391,27 @@ void MAVLinkProtocol::enableLogging(bool enabled) ...@@ -391,21 +391,27 @@ void MAVLinkProtocol::enableLogging(bool enabled)
{ {
if (enabled && !m_loggingEnabled) if (enabled && !m_loggingEnabled)
{ {
m_logfile = new QFile(getLogfileName()); if (m_logfile->isOpen()) m_logfile->close();
m_logfile->open(QIODevice::WriteOnly | QIODevice::Append); m_logfile->open(QIODevice::WriteOnly | QIODevice::Append);
} }
else else if (!enabled)
{ {
m_logfile->close(); m_logfile->close();
delete m_logfile;
m_logfile = NULL;
} }
m_loggingEnabled = enabled; m_loggingEnabled = enabled;
emit loggingChanged(enabled);
}
void MAVLinkProtocol::setLogfileName(const QString& filename)
{
m_logfile->close();
m_logfile->setFileName(filename);
} }
void MAVLinkProtocol::enableVersionCheck(bool enabled) void MAVLinkProtocol::enableVersionCheck(bool enabled)
{ {
m_enable_version_check = enabled; m_enable_version_check = enabled;
emit versionCheckChanged(enabled);
} }
bool MAVLinkProtocol::heartbeatsEnabled(void) bool MAVLinkProtocol::heartbeatsEnabled(void)
......
...@@ -70,8 +70,10 @@ public: ...@@ -70,8 +70,10 @@ public:
bool loggingEnabled(void); bool loggingEnabled(void);
/** @brief Get protocol version check state */ /** @brief Get protocol version check state */
bool versionCheckEnabled(void); bool versionCheckEnabled(void);
/** @brief Get the protocol version */
int getVersion() { return MAVLINK_VERSION; }
/** @brief Get the name of the packet log file */ /** @brief Get the name of the packet log file */
static QString getLogfileName(); QString getLogfileName();
public slots: public slots:
/** @brief Receive bytes from a communication interface */ /** @brief Receive bytes from a communication interface */
...@@ -89,6 +91,9 @@ public slots: ...@@ -89,6 +91,9 @@ public slots:
/** @brief Enable/disable binary packet logging */ /** @brief Enable/disable binary packet logging */
void enableLogging(bool enabled); void enableLogging(bool enabled);
/** @brief Set log file name */
void setLogfileName(const QString& filename);
/** @brief Enable / disable version check */ /** @brief Enable / disable version check */
void enableVersionCheck(bool enabled); void enableVersionCheck(bool enabled);
......
...@@ -97,8 +97,8 @@ MAVLinkSimulationLink::MAVLinkSimulationLink(QString readFile, QString writeFile ...@@ -97,8 +97,8 @@ MAVLinkSimulationLink::MAVLinkSimulationLink(QString readFile, QString writeFile
LinkManager::instance()->add(this); LinkManager::instance()->add(this);
// Open packet log // Open packet log
mavlinkLogFile = new QFile(MAVLinkProtocol::getLogfileName()); mavlinkLogFile = new QFile();
mavlinkLogFile->open(QIODevice::ReadOnly); //mavlinkLogFile->open(QIODevice::ReadOnly);
} }
MAVLinkSimulationLink::~MAVLinkSimulationLink() MAVLinkSimulationLink::~MAVLinkSimulationLink()
...@@ -141,7 +141,7 @@ void MAVLinkSimulationLink::run() ...@@ -141,7 +141,7 @@ void MAVLinkSimulationLink::run()
} }
last = MG::TIME::getGroundTimeNow(); last = MG::TIME::getGroundTimeNow();
} }
MG::SLEEP::msleep(2); MG::SLEEP::msleep(3);
} }
} }
......
...@@ -108,8 +108,9 @@ void SerialLink::loadSettings() ...@@ -108,8 +108,9 @@ void SerialLink::loadSettings()
setPortName(settings.value("SERIALLINK_COMM_PORT").toString()); setPortName(settings.value("SERIALLINK_COMM_PORT").toString());
setBaudRateType(settings.value("SERIALLINK_COMM_BAUD").toInt()); setBaudRateType(settings.value("SERIALLINK_COMM_BAUD").toInt());
setParityType(settings.value("SERIALLINK_COMM_PARITY").toInt()); setParityType(settings.value("SERIALLINK_COMM_PARITY").toInt());
setStopBitsType(settings.value("SERIALLINK_COMM_STOPBITS").toInt()); setStopBits(settings.value("SERIALLINK_COMM_STOPBITS").toInt());
setDataBitsType(settings.value("SERIALLINK_COMM_DATABITS").toInt()); setDataBits(settings.value("SERIALLINK_COMM_DATABITS").toInt());
setFlowType(settings.value("SERIALLINK_COMM_FLOW_CONTROL").toInt());
} }
} }
...@@ -120,8 +121,9 @@ void SerialLink::writeSettings() ...@@ -120,8 +121,9 @@ void SerialLink::writeSettings()
settings.setValue("SERIALLINK_COMM_PORT", this->porthandle); settings.setValue("SERIALLINK_COMM_PORT", this->porthandle);
settings.setValue("SERIALLINK_COMM_BAUD", getBaudRateType()); settings.setValue("SERIALLINK_COMM_BAUD", getBaudRateType());
settings.setValue("SERIALLINK_COMM_PARITY", getParityType()); settings.setValue("SERIALLINK_COMM_PARITY", getParityType());
settings.setValue("SERIALLINK_COMM_STOPBITS", getStopBitsType()); settings.setValue("SERIALLINK_COMM_STOPBITS", getStopBits());
settings.setValue("SERIALLINK_COMM_DATABITS", getDataBitsType()); settings.setValue("SERIALLINK_COMM_DATABITS", getDataBits());
settings.setValue("SERIALLINK_COMM_FLOW_CONTROL", getFlowType());
settings.sync(); settings.sync();
} }
...@@ -316,10 +318,10 @@ bool SerialLink::hardwareConnect() ...@@ -316,10 +318,10 @@ bool SerialLink::hardwareConnect()
{ {
emit connected(); emit connected();
emit connected(true); emit connected(true);
writeSettings();
} }
writeSettings();
return connectionUp; return connectionUp;
} }
...@@ -531,6 +533,48 @@ int SerialLink::getStopBitsType() ...@@ -531,6 +533,48 @@ int SerialLink::getStopBitsType()
return stopBits; 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) bool SerialLink::setPortName(QString portName)
{ {
if(portName.trimmed().length() > 0) if(portName.trimmed().length() > 0)
...@@ -845,8 +889,7 @@ bool SerialLink::setParityType(int parity) ...@@ -845,8 +889,7 @@ bool SerialLink::setParityType(int parity)
} }
// FIXME Works not as anticipated by user! bool SerialLink::setDataBits(int dataBits)
bool SerialLink::setDataBitsType(int dataBits)
{ {
bool accepted = true; bool accepted = true;
...@@ -879,12 +922,12 @@ bool SerialLink::setDataBitsType(int dataBits) ...@@ -879,12 +922,12 @@ bool SerialLink::setDataBitsType(int dataBits)
return accepted; return accepted;
} }
// FIXME WORKS NOT AS ANTICIPATED BY USER! bool SerialLink::setStopBits(int stopBits)
bool SerialLink::setStopBitsType(int stopBits)
{ {
bool reconnect = false; bool reconnect = false;
bool accepted = true; bool accepted = true;
if(isConnected()) { if(isConnected())
{
disconnect(); disconnect();
reconnect = true; reconnect = true;
} }
...@@ -907,3 +950,51 @@ bool SerialLink::setStopBitsType(int stopBits) ...@@ -907,3 +950,51 @@ bool SerialLink::setStopBitsType(int stopBits)
if(reconnect) connect(); if(reconnect) connect();
return accepted; 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: ...@@ -74,6 +74,10 @@ public:
*/ */
QString getName(); QString getName();
int getBaudRate(); int getBaudRate();
int getDataBits();
int getStopBits();
// ENUM values
int getBaudRateType(); int getBaudRateType();
int getFlowType(); int getFlowType();
int getParityType(); int getParityType();
...@@ -103,6 +107,10 @@ public: ...@@ -103,6 +107,10 @@ public:
public slots: public slots:
bool setPortName(QString portName); bool setPortName(QString portName);
bool setBaudRate(int rate); bool setBaudRate(int rate);
bool setDataBits(int dataBits);
bool setStopBits(int stopBits);
// Set ENUM values
bool setBaudRateType(int rateIndex); bool setBaudRateType(int rateIndex);
bool setFlowType(int flow); bool setFlowType(int flow);
bool setParityType(int parity); bool setParityType(int parity);
......
...@@ -43,6 +43,9 @@ class SerialLinkInterface : public LinkInterface { ...@@ -43,6 +43,9 @@ class SerialLinkInterface : public LinkInterface {
public: public:
virtual QString getPortName() = 0; virtual QString getPortName() = 0;
virtual int getBaudRate() = 0; virtual int getBaudRate() = 0;
virtual int getDataBits() = 0;
virtual int getStopBits() = 0;
virtual int getBaudRateType() = 0; virtual int getBaudRateType() = 0;
virtual int getFlowType() = 0; virtual int getFlowType() = 0;
virtual int getParityType() = 0; virtual int getParityType() = 0;
......
...@@ -49,7 +49,7 @@ UDPLink::UDPLink(QHostAddress host, quint16 port) ...@@ -49,7 +49,7 @@ UDPLink::UDPLink(QHostAddress host, quint16 port)
// Set unique ID and add link to the list of links // Set unique ID and add link to the list of links
this->id = getNextLinkId(); this->id = getNextLinkId();
this->name = tr("UDP link ") + QString::number(getId()); this->name = tr("UDP Link (port:%1)").arg(14550);
LinkManager::instance()->add(this); LinkManager::instance()->add(this);
} }
......
...@@ -663,12 +663,12 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message) ...@@ -663,12 +663,12 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
mavlink_nav_filter_bias_t bias; mavlink_nav_filter_bias_t bias;
mavlink_msg_nav_filter_bias_decode(&message, &bias); mavlink_msg_nav_filter_bias_decode(&message, &bias);
quint64 time = MG::TIME::getGroundTimeNow(); quint64 time = MG::TIME::getGroundTimeNow();
emit valueChanged(uasId, "b_f[0]", bias.accel_0, time); emit valueChanged(uasId, "b_f[0]", "raw", bias.accel_0, time);
emit valueChanged(uasId, "b_f[1]", bias.accel_1, time); emit valueChanged(uasId, "b_f[1]", "raw", bias.accel_1, time);
emit valueChanged(uasId, "b_f[2]", bias.accel_2, time); emit valueChanged(uasId, "b_f[2]", "raw", bias.accel_2, time);
emit valueChanged(uasId, "b_w[0]", bias.gyro_0, time); emit valueChanged(uasId, "b_w[0]", "raw", bias.gyro_0, time);
emit valueChanged(uasId, "b_w[1]", bias.gyro_1, time); emit valueChanged(uasId, "b_w[1]", "raw", bias.gyro_1, time);
emit valueChanged(uasId, "b_w[2]", bias.gyro_2, time); emit valueChanged(uasId, "b_w[2]", "raw", bias.gyro_2, time);
} }
break; break;
case MAVLINK_MSG_ID_RADIO_CALIBRATION: case MAVLINK_MSG_ID_RADIO_CALIBRATION:
......
...@@ -55,6 +55,7 @@ void UASWaypointManager::timeout() ...@@ -55,6 +55,7 @@ void UASWaypointManager::timeout()
{ {
protocol_timer.start(PROTOCOL_TIMEOUT_MS); protocol_timer.start(PROTOCOL_TIMEOUT_MS);
current_retries--; current_retries--;
emit updateStatusString(tr("Timeout, retrying (retries left: %1)").arg(current_retries));
qDebug() << "Timeout, retrying (retries left:" << current_retries << ")"; qDebug() << "Timeout, retrying (retries left:" << current_retries << ")";
if (current_state == WP_GETLIST) if (current_state == WP_GETLIST)
{ {
...@@ -517,7 +518,7 @@ void UASWaypointManager::sendWaypointClearAll() ...@@ -517,7 +518,7 @@ void UASWaypointManager::sendWaypointClearAll()
wpca.target_system = uas.getUASID(); wpca.target_system = uas.getUASID();
wpca.target_component = MAV_COMP_ID_WAYPOINTPLANNER; 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); mavlink_msg_waypoint_clear_all_encode(uas.mavlink->getSystemId(), uas.mavlink->getComponentId(), &message, &wpca);
uas.sendMessage(message); uas.sendMessage(message);
...@@ -554,7 +555,7 @@ void UASWaypointManager::sendWaypointCount() ...@@ -554,7 +555,7 @@ void UASWaypointManager::sendWaypointCount()
wpc.count = current_count; wpc.count = current_count;
qDebug() << "sent waypoint count (" << wpc.count << ") to ID " << wpc.target_system; 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); mavlink_msg_waypoint_count_encode(uas.mavlink->getSystemId(), uas.mavlink->getComponentId(), &message, &wpc);
uas.sendMessage(message); uas.sendMessage(message);
...@@ -571,7 +572,7 @@ void UASWaypointManager::sendWaypointRequestList() ...@@ -571,7 +572,7 @@ void UASWaypointManager::sendWaypointRequestList()
wprl.target_system = uas.getUASID(); wprl.target_system = uas.getUASID();
wprl.target_component = MAV_COMP_ID_WAYPOINTPLANNER; 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); mavlink_msg_waypoint_request_list_encode(uas.mavlink->getSystemId(), uas.mavlink->getComponentId(), &message, &wprl);
uas.sendMessage(message); uas.sendMessage(message);
...@@ -591,7 +592,7 @@ void UASWaypointManager::sendWaypointRequest(quint16 seq) ...@@ -591,7 +592,7 @@ void UASWaypointManager::sendWaypointRequest(quint16 seq)
wpr.target_component = MAV_COMP_ID_WAYPOINTPLANNER; wpr.target_component = MAV_COMP_ID_WAYPOINTPLANNER;
wpr.seq = seq; 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); mavlink_msg_waypoint_request_encode(uas.mavlink->getSystemId(), uas.mavlink->getComponentId(), &message, &wpr);
uas.sendMessage(message); uas.sendMessage(message);
...@@ -612,7 +613,7 @@ void UASWaypointManager::sendWaypoint(quint16 seq) ...@@ -612,7 +613,7 @@ void UASWaypointManager::sendWaypoint(quint16 seq)
wp->target_system = uas.getUASID(); wp->target_system = uas.getUASID();
wp->target_component = MAV_COMP_ID_WAYPOINTPLANNER; 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); mavlink_msg_waypoint_encode(uas.mavlink->getSystemId(), uas.mavlink->getComponentId(), &message, wp);
uas.sendMessage(message); uas.sendMessage(message);
......
...@@ -106,7 +106,7 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn ...@@ -106,7 +106,7 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn
QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, ui.linkGroupBox); QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, ui.linkGroupBox);
layout->addWidget(conf); layout->addWidget(conf);
ui.linkGroupBox->setLayout(layout); ui.linkGroupBox->setLayout(layout);
ui.linkGroupBox->setTitle(tr("serial link")); ui.linkGroupBox->setTitle(tr("Serial Link"));
//ui.linkGroupBox->setTitle(link->getName()); //ui.linkGroupBox->setTitle(link->getName());
//connect(link, SIGNAL(nameChanged(QString)), ui.linkGroupBox, SLOT(setTitle(QString))); //connect(link, SIGNAL(nameChanged(QString)), ui.linkGroupBox, SLOT(setTitle(QString)));
} }
...@@ -142,13 +142,13 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn ...@@ -142,13 +142,13 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn
// Open details pane for MAVLink if necessary // Open details pane for MAVLink if necessary
MAVLinkProtocol* mavlink = dynamic_cast<MAVLinkProtocol*>(protocol); MAVLinkProtocol* mavlink = dynamic_cast<MAVLinkProtocol*>(protocol);
if(mavlink != 0) if (mavlink != 0)
{ {
QWidget* conf = new MAVLinkSettingsWidget(mavlink, this); QWidget* conf = new MAVLinkSettingsWidget(mavlink, this);
QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, ui.protocolGroupBox); QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, ui.protocolGroupBox);
layout->addWidget(conf); layout->addWidget(conf);
ui.protocolGroupBox->setLayout(layout); ui.protocolGroupBox->setLayout(layout);
ui.protocolGroupBox->setTitle(protocol->getName()); ui.protocolGroupBox->setTitle(protocol->getName()+" (Global Settings)");
} }
else else
{ {
......
...@@ -105,6 +105,8 @@ DebugConsole::DebugConsole(QWidget *parent) : ...@@ -105,6 +105,8 @@ DebugConsole::DebugConsole(QWidget *parent) :
connect(m_ui->holdButton, SIGNAL(toggled(bool)), this, SLOT(hold(bool))); connect(m_ui->holdButton, SIGNAL(toggled(bool)), this, SLOT(hold(bool)));
// Connect connect button // Connect connect button
connect(m_ui->connectButton, SIGNAL(clicked()), this, SLOT(handleConnectButton())); 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); this->setVisible(false);
} }
...@@ -327,8 +329,78 @@ void DebugConsole::receiveBytes(LinkInterface* link, QByteArray bytes) ...@@ -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() 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; QByteArray transmit;
QString feedback; QString feedback;
bool ok = true; bool ok = true;
...@@ -382,8 +454,16 @@ void DebugConsole::sendBytes() ...@@ -382,8 +454,16 @@ void DebugConsole::sendBytes()
if (ok && m_ui->sendText->text().toLatin1().size() > 0) if (ok && m_ui->sendText->text().toLatin1().size() > 0)
{ {
// Transmit only if conversion succeeded // Transmit only if conversion succeeded
currLink->writeBytes(transmit, transmit.size()); // int transmitted =
m_ui->sentText->setText(tr("Sent: ") + feedback); 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) else if (m_ui->sendText->text().toLatin1().size() > 0)
{ {
...@@ -403,6 +483,8 @@ void DebugConsole::hexModeEnabled(bool mode) ...@@ -403,6 +483,8 @@ void DebugConsole::hexModeEnabled(bool mode)
{ {
convertToAscii = !mode; convertToAscii = !mode;
m_ui->receiveText->clear(); m_ui->receiveText->clear();
m_ui->sendText->clear();
m_ui->sentText->clear();
} }
/** /**
......
...@@ -83,6 +83,8 @@ public slots: ...@@ -83,6 +83,8 @@ public slots:
void setAutoHold(bool hold); void setAutoHold(bool hold);
/** @brief Receive plain text message to output to the user */ /** @brief Receive plain text message to output to the user */
void receiveTextMessage(int id, int component, int severity, QString text); void receiveTextMessage(int id, int component, int severity, QString text);
/** @brief Append a special symbol */
void appendSpecialSymbol(const QString& text);
protected slots: protected slots:
/** @brief Draw information overlay */ /** @brief Draw information overlay */
...@@ -92,6 +94,7 @@ public slots: ...@@ -92,6 +94,7 @@ public slots:
protected: protected:
void changeEvent(QEvent *e); void changeEvent(QEvent *e);
QByteArray symbolNameToBytes(const QString& symbol);
QList<LinkInterface*> links; QList<LinkInterface*> links;
LinkInterface* currLink; LinkInterface* currLink;
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>463</width> <width>447</width>
<height>159</height> <height>181</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
...@@ -106,24 +106,74 @@ ...@@ -106,24 +106,74 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="4" column="1">
<widget class="QLineEdit" name="sendText"> <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,10,10,10,0">
<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">
<property name="spacing"> <property name="spacing">
<number>5</number> <number>5</number>
</property> </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> <item>
<widget class="QPushButton" name="transmitButton"> <widget class="QPushButton" name="transmitButton">
<property name="toolTip"> <property name="toolTip">
...@@ -164,6 +214,19 @@ ...@@ -164,6 +214,19 @@
</item> </item>
</layout> </layout>
</item> </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> </layout>
</widget> </widget>
<resources> <resources>
......
...@@ -812,6 +812,7 @@ float HDDisplay::refLineWidthToPen(float line) ...@@ -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) void HDDisplay::updateValue(const int uasId, const QString& name, const QString& unit, const double value, const quint64 msec)
{ {
Q_UNUSED(uasId); Q_UNUSED(uasId);
Q_UNUSED(unit);
// Update mean // Update mean
const float oldMean = valuesMean.value(name, 0.0f); const float oldMean = valuesMean.value(name, 0.0f);
const int meanCount = valuesCount.value(name, 0); const int meanCount = valuesCount.value(name, 0);
......
...@@ -27,6 +27,11 @@ This file is part of the QGROUNDCONTROL project ...@@ -27,6 +27,11 @@ This file is part of the QGROUNDCONTROL project
* @author Lorenz Meier <mail@qgroundcontrol.org> * @author Lorenz Meier <mail@qgroundcontrol.org>
*/ */
#include <QFileInfo>
#include <QFileDialog>
#include <QMessageBox>
#include <QDesktopServices>
#include "MAVLinkSettingsWidget.h" #include "MAVLinkSettingsWidget.h"
#include "ui_MAVLinkSettingsWidget.h" #include "ui_MAVLinkSettingsWidget.h"
...@@ -37,6 +42,8 @@ MAVLinkSettingsWidget::MAVLinkSettingsWidget(MAVLinkProtocol* protocol, QWidget ...@@ -37,6 +42,8 @@ MAVLinkSettingsWidget::MAVLinkSettingsWidget(MAVLinkProtocol* protocol, QWidget
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
m_ui->gridLayout->setAlignment(Qt::AlignTop);
// Initialize state // Initialize state
m_ui->heartbeatCheckBox->setChecked(protocol->heartbeatsEnabled()); m_ui->heartbeatCheckBox->setChecked(protocol->heartbeatsEnabled());
m_ui->loggingCheckBox->setChecked(protocol->loggingEnabled()); m_ui->loggingCheckBox->setChecked(protocol->loggingEnabled());
...@@ -49,7 +56,59 @@ MAVLinkSettingsWidget::MAVLinkSettingsWidget(MAVLinkProtocol* protocol, QWidget ...@@ -49,7 +56,59 @@ MAVLinkSettingsWidget::MAVLinkSettingsWidget(MAVLinkProtocol* protocol, QWidget
connect(m_ui->loggingCheckBox, SIGNAL(toggled(bool)), protocol, SLOT(enableLogging(bool))); connect(m_ui->loggingCheckBox, SIGNAL(toggled(bool)), protocol, SLOT(enableLogging(bool)));
connect(protocol, SIGNAL(versionCheckChanged(bool)), m_ui->versionCheckBox, SLOT(setChecked(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->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() MAVLinkSettingsWidget::~MAVLinkSettingsWidget()
......
...@@ -15,6 +15,12 @@ public: ...@@ -15,6 +15,12 @@ public:
MAVLinkSettingsWidget(MAVLinkProtocol* protocol, QWidget *parent = 0); MAVLinkSettingsWidget(MAVLinkProtocol* protocol, QWidget *parent = 0);
~MAVLinkSettingsWidget(); ~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: protected:
MAVLinkProtocol* protocol; MAVLinkProtocol* protocol;
void changeEvent(QEvent *e); void changeEvent(QEvent *e);
......
...@@ -6,51 +6,85 @@ ...@@ -6,51 +6,85 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>267</width> <width>361</width>
<height>123</height> <height>145</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QGridLayout" name="gridLayout" columnstretch="1,100,1">
<property name="margin"> <item row="0" column="0" colspan="3">
<number>6</number>
</property>
<item>
<widget class="QCheckBox" name="heartbeatCheckBox"> <widget class="QCheckBox" name="heartbeatCheckBox">
<property name="text"> <property name="text">
<string>Emit heartbeat</string> <string>Emit heartbeat</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="1" column="0" colspan="3">
<widget class="QCheckBox" name="loggingCheckBox"> <widget class="QCheckBox" name="loggingCheckBox">
<property name="text"> <property name="text">
<string>Log all MAVLink packets</string> <string>Log all MAVLink packets</string>
</property> </property>
</widget> </widget>
</item> </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"> <widget class="QCheckBox" name="versionCheckBox">
<property name="text"> <property name="text">
<string>Only accept MAVs with same protocol version</string> <string>Only accept MAVs with same protocol version</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="5" column="0">
<spacer name="verticalSpacer"> <spacer name="versionSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>8</width>
<height>84</height> <height>0</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </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> </layout>
</widget> </widget>
<resources/> <resources/>
......
This diff is collapsed.
...@@ -104,6 +104,9 @@ public slots: ...@@ -104,6 +104,9 @@ public slots:
void addLink(); void addLink();
void addLink(LinkInterface* link); void addLink(LinkInterface* link);
void configure(); void configure();
/** @brief Set the currently controlled UAS */
void setActiveUAS(UASInterface* uas);
/** @brief Add a new UAS */
void UASCreated(UASInterface* uas); void UASCreated(UASInterface* uas);
void startVideoCapture(); void startVideoCapture();
void stopVideoCapture(); void stopVideoCapture();
...@@ -208,6 +211,7 @@ protected: ...@@ -208,6 +211,7 @@ protected:
MENU_SLUGS_PID, MENU_SLUGS_PID,
MENU_SLUGS_HIL, MENU_SLUGS_HIL,
MENU_SLUGS_CAMERA, MENU_SLUGS_CAMERA,
MENU_MAVLINK_LOG_PLAYER,
CENTRAL_SEPARATOR= 255, // do not change CENTRAL_SEPARATOR= 255, // do not change
CENTRAL_LINECHART, CENTRAL_LINECHART,
CENTRAL_PROTOCOL, CENTRAL_PROTOCOL,
...@@ -297,6 +301,7 @@ protected: ...@@ -297,6 +301,7 @@ protected:
/** @brief Keeps track of the current view */ /** @brief Keeps track of the current view */
VIEW_SECTIONS currentView; VIEW_SECTIONS currentView;
bool aboutToCloseFlag; bool aboutToCloseFlag;
bool changingViewsFlag;
void clearView(); void clearView();
...@@ -360,6 +365,7 @@ protected: ...@@ -360,6 +365,7 @@ protected:
QPointer<QDockWidget> watchdogControlDockWidget; QPointer<QDockWidget> watchdogControlDockWidget;
QPointer<QDockWidget> headUpDockWidget; QPointer<QDockWidget> headUpDockWidget;
QPointer<QDockWidget> logPlayerDockWidget;
QPointer<QDockWidget> hsiDockWidget; QPointer<QDockWidget> hsiDockWidget;
QPointer<QDockWidget> rcViewDockWidget; QPointer<QDockWidget> rcViewDockWidget;
......
...@@ -49,23 +49,30 @@ ...@@ -49,23 +49,30 @@
<addaction name="actionNewCustomWidget"/> <addaction name="actionNewCustomWidget"/>
<addaction name="actionMuteAudioOutput"/> <addaction name="actionMuteAudioOutput"/>
<addaction name="actionSimulate"/> <addaction name="actionSimulate"/>
<addaction name="actionPreferences"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionReloadStyle"/> <addaction name="actionReloadStyle"/>
<addaction name="actionExit"/> <addaction name="actionExit"/>
</widget> </widget>
<widget class="QMenu" name="menuNetwork"> <widget class="QMenu" name="menuNetwork">
<property name="title"> <property name="title">
<string>Network</string> <string>Communication</string>
</property> </property>
<addaction name="actionAdd_Link"/> <addaction name="actionAdd_Link"/>
<addaction name="separator"/> <addaction name="separator"/>
</widget> </widget>
<widget class="QMenu" name="menuConnected_Systems"> <widget class="QMenu" name="menuConnected_Systems">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title"> <property name="title">
<string>Select System</string> <string>Select System</string>
</property> </property>
</widget> </widget>
<widget class="QMenu" name="menuUnmanned_System"> <widget class="QMenu" name="menuUnmanned_System">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title"> <property name="title">
<string>Unmanned System</string> <string>Unmanned System</string>
</property> </property>
...@@ -76,8 +83,6 @@ ...@@ -76,8 +83,6 @@
<addaction name="actionLand"/> <addaction name="actionLand"/>
<addaction name="actionEmergency_Land"/> <addaction name="actionEmergency_Land"/>
<addaction name="actionEmergency_Kill"/> <addaction name="actionEmergency_Kill"/>
<addaction name="separator"/>
<addaction name="actionConfiguration"/>
</widget> </widget>
<widget class="QMenu" name="menuTools"> <widget class="QMenu" name="menuTools">
<property name="title"> <property name="title">
...@@ -124,6 +129,9 @@ ...@@ -124,6 +129,9 @@
</property> </property>
</action> </action>
<action name="actionLiftoff"> <action name="actionLiftoff">
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon"> <property name="icon">
<iconset resource="../../mavground.qrc"> <iconset resource="../../mavground.qrc">
<normaloff>:/images/control/launch.svg</normaloff> <normaloff>:/images/control/launch.svg</normaloff>
...@@ -143,6 +151,10 @@ ...@@ -143,6 +151,10 @@
</property> </property>
</action> </action>
<action name="actionEmergency_Land"> <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"> <property name="text">
<string>Emergency Land</string> <string>Emergency Land</string>
</property> </property>
...@@ -151,6 +163,10 @@ ...@@ -151,6 +163,10 @@
</property> </property>
</action> </action>
<action name="actionEmergency_Kill"> <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"> <property name="text">
<string>Kill UAS</string> <string>Kill UAS</string>
</property> </property>
...@@ -312,6 +328,10 @@ ...@@ -312,6 +328,10 @@
</property> </property>
</action> </action>
<action name="actionNewCustomWidget"> <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"> <property name="text">
<string>New Custom Widget</string> <string>New Custom Widget</string>
</property> </property>
...@@ -332,6 +352,18 @@ ...@@ -332,6 +352,18 @@
<string>Mute Audio Output</string> <string>Mute Audio Output</string>
</property> </property>
</action> </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> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources> <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) ...@@ -239,12 +239,17 @@ userConfigured(false)
// Setup the user interface according to link type // Setup the user interface according to link type
ui.setupUi(this); ui.setupUi(this);
//this->setVisible(false);
//this->hide();
// Create action to open this menu // Create action to open this menu
// Create configuration action for this link // Create configuration action for this link
// Connect the current UAS // Connect the current UAS
action = new QAction(QIcon(":/images/devices/network-wireless.svg"), "", link); action = new QAction(QIcon(":/images/devices/network-wireless.svg"), "", link);
setLinkName(link->getName()); setLinkName(link->getName());
setupPortList();
connect(action, SIGNAL(triggered()), this, SLOT(configureCommunication())); connect(action, SIGNAL(triggered()), this, SLOT(configureCommunication()));
// Make sure that a change in the link name will be reflected in the UI // Make sure that a change in the link name will be reflected in the UI
...@@ -258,10 +263,8 @@ userConfigured(false) ...@@ -258,10 +263,8 @@ userConfigured(false)
connect(ui.parNone, SIGNAL(toggled(bool)), this, SLOT(setParityNone())); connect(ui.parNone, SIGNAL(toggled(bool)), this, SLOT(setParityNone()));
connect(ui.parOdd, SIGNAL(toggled(bool)), this, SLOT(setParityOdd())); connect(ui.parOdd, SIGNAL(toggled(bool)), this, SLOT(setParityOdd()));
connect(ui.parEven, SIGNAL(toggled(bool)), this, SLOT(setParityEven())); connect(ui.parEven, SIGNAL(toggled(bool)), this, SLOT(setParityEven()));
connect(ui.dataBitsSpinBox, SIGNAL(valueChanged(int)), this->link, SLOT(setDataBitsType(int))); connect(ui.dataBitsSpinBox, SIGNAL(valueChanged(int)), this->link, SLOT(setDataBits(int)));
connect(ui.stopBitsSpinBox, SIGNAL(valueChanged(int)), this->link, SLOT(setStopBitsType(int))); connect(ui.stopBitsSpinBox, SIGNAL(valueChanged(int)), this->link, SLOT(setStopBits(int)));
setupPortList();
//connect(this->link, SIGNAL(connected(bool)), this, SLOT()); //connect(this->link, SIGNAL(connected(bool)), this, SLOT());
ui.portName->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow); ui.portName->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow);
...@@ -299,8 +302,8 @@ userConfigured(false) ...@@ -299,8 +302,8 @@ userConfigured(false)
ui.baudRate->setCurrentIndex(this->link->getBaudRateType()); ui.baudRate->setCurrentIndex(this->link->getBaudRateType());
ui.dataBitsSpinBox->setValue(this->link->getDataBitsType() + 5); ui.dataBitsSpinBox->setValue(this->link->getDataBits());
ui.stopBitsSpinBox->setValue(this->link->getStopBitsType() + 1); ui.stopBitsSpinBox->setValue(this->link->getStopBits());
portCheckTimer = new QTimer(this); portCheckTimer = new QTimer(this);
portCheckTimer->setInterval(1000); portCheckTimer->setInterval(1000);
...@@ -308,7 +311,7 @@ userConfigured(false) ...@@ -308,7 +311,7 @@ userConfigured(false)
// Display the widget // Display the widget
this->window()->setWindowTitle(tr("Serial Communication Settings")); this->window()->setWindowTitle(tr("Serial Communication Settings"));
this->show(); //this->show();
} }
else else
{ {
...@@ -323,18 +326,14 @@ SerialConfigurationWindow::~SerialConfigurationWindow() { ...@@ -323,18 +326,14 @@ SerialConfigurationWindow::~SerialConfigurationWindow() {
void SerialConfigurationWindow::showEvent(QShowEvent* event) void SerialConfigurationWindow::showEvent(QShowEvent* event)
{ {
if (event->isAccepted()) Q_UNUSED(event);
{ portCheckTimer->start();
portCheckTimer->start();
}
} }
void SerialConfigurationWindow::hideEvent(QHideEvent* event) void SerialConfigurationWindow::hideEvent(QHideEvent* event)
{ {
if (event->isAccepted()) Q_UNUSED(event);
{ portCheckTimer->stop();
portCheckTimer->stop();
}
} }
QAction* SerialConfigurationWindow::getAction() QAction* SerialConfigurationWindow::getAction()
......
...@@ -119,8 +119,7 @@ updateTimer(new QTimer()) ...@@ -119,8 +119,7 @@ updateTimer(new QTimer())
curvesWidgetLayout->addWidget(value, labelRow, 3); curvesWidgetLayout->addWidget(value, labelRow, 3);
// Unit // Unit
label->setText("Unit"); //curvesWidgetLayout->addWidget(new QLabel(tr("Unit")), labelRow, 4);
curvesWidgetLayout->addWidget(new QLabel(tr("Unit")), labelRow, 4);
// Mean // Mean
mean = new QLabel(this); mean = new QLabel(this);
...@@ -216,9 +215,8 @@ void LinechartWidget::createLayout() ...@@ -216,9 +215,8 @@ void LinechartWidget::createLayout()
connect(logButton, SIGNAL(clicked()), this, SLOT(startLogging())); connect(logButton, SIGNAL(clicked()), this, SLOT(startLogging()));
// Ground time button // Ground time button
QToolButton* timeButton = new QToolButton(this); QCheckBox* timeButton = new QCheckBox(this);
timeButton->setText(tr("Ground Time")); 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->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.")); 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; bool gTimeDefault = true;
...@@ -228,6 +226,13 @@ void LinechartWidget::createLayout() ...@@ -228,6 +226,13 @@ void LinechartWidget::createLayout()
layout->setColumnStretch(4, 0); layout->setColumnStretch(4, 0);
connect(timeButton, SIGNAL(clicked(bool)), activePlot, SLOT(enforceGroundTime(bool))); 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 // Create the scroll bar
//scrollbar = new QScrollBar(Qt::Horizontal, ui.diagramGroupBox); //scrollbar = new QScrollBar(Qt::Horizontal, ui.diagramGroupBox);
//scrollbar->setMinimum(MIN_TIME_SCROLLBAR_VALUE); //scrollbar->setMinimum(MIN_TIME_SCROLLBAR_VALUE);
...@@ -241,7 +246,7 @@ void LinechartWidget::createLayout() ...@@ -241,7 +246,7 @@ void LinechartWidget::createLayout()
// Add scroll bar to layout and make sure it gets all available space // Add scroll bar to layout and make sure it gets all available space
//layout->addWidget(scrollbar, 1, 5); //layout->addWidget(scrollbar, 1, 5);
layout->setColumnStretch(5, 10); //layout->setColumnStretch(5, 10);
ui.diagramGroupBox->setLayout(layout); ui.diagramGroupBox->setLayout(layout);
...@@ -254,8 +259,8 @@ void LinechartWidget::createLayout() ...@@ -254,8 +259,8 @@ void LinechartWidget::createLayout()
// FIXME // FIXME
// Connect notifications from the plot to the user interface // Connect notifications from the plot to the user interface
connect(activePlot, SIGNAL(curveAdded(QString)), this, SLOT(addCurve(QString))); //connect(activePlot, SIGNAL(curveAdded(QString)), this, SLOT(addCurve(QString)));
connect(activePlot, SIGNAL(curveRemoved(QString)), this, SLOT(removeCurve(QString))); //connect(activePlot, SIGNAL(curveRemoved(QString)), this, SLOT(removeCurve(QString)));
// Scrollbar // Scrollbar
...@@ -313,7 +318,7 @@ void LinechartWidget::appendData(int uasId, const QString& curve, const QString& ...@@ -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 // Make sure the curve will be created if it does not yet exist
if(!label) if(!label)
{ {
qDebug() << "ADDING CURVE IN APPENDDATE DOUBLE"; //qDebug() << "ADDING CURVE IN APPENDDATE DOUBLE";
addCurve(curve, unit); addCurve(curve, unit);
} }
} }
...@@ -594,8 +599,8 @@ void LinechartWidget::addCurve(const QString& curve, const QString& unit) ...@@ -594,8 +599,8 @@ void LinechartWidget::addCurve(const QString& curve, const QString& unit)
value = new QLabel(this); value = new QLabel(this);
value->setNum(0.00); value->setNum(0.00);
value->setStyleSheet(QString("QLabel {font-family:\"Courier\"; font-weight: bold;}")); value->setStyleSheet(QString("QLabel {font-family:\"Courier\"; font-weight: bold;}"));
value->setToolTip(tr("Current value of ") + curve); value->setToolTip(tr("Current value of %1 in %2 units").arg(curve, unit));
value->setWhatsThis(tr("Current value of ") + curve); value->setWhatsThis(tr("Current value of %1 in %2 units").arg(curve, unit));
curveLabels->insert(curve+unit, value); curveLabels->insert(curve+unit, value);
curvesWidgetLayout->addWidget(value, labelRow, 3); curvesWidgetLayout->addWidget(value, labelRow, 3);
...@@ -603,17 +608,18 @@ void LinechartWidget::addCurve(const QString& curve, const QString& unit) ...@@ -603,17 +608,18 @@ void LinechartWidget::addCurve(const QString& curve, const QString& unit)
unitLabel = new QLabel(this); unitLabel = new QLabel(this);
unitLabel->setText(unit); unitLabel->setText(unit);
unitLabel->setStyleSheet(QString("QLabel {color: %1;}").arg("#AAAAAA")); unitLabel->setStyleSheet(QString("QLabel {color: %1;}").arg("#AAAAAA"));
qDebug() << "UNIT" << unit; //qDebug() << "UNIT" << unit;
unitLabel->setToolTip(tr("Unit of ") + curve); unitLabel->setToolTip(tr("Unit of ") + curve);
unitLabel->setWhatsThis(tr("Unit of ") + curve); unitLabel->setWhatsThis(tr("Unit of ") + curve);
curvesWidgetLayout->addWidget(unitLabel, labelRow, 4); curvesWidgetLayout->addWidget(unitLabel, labelRow, 4);
connect(unitsCheckBox, SIGNAL(clicked(bool)), unitLabel, SLOT(setVisible(bool)));
// Mean // Mean
mean = new QLabel(this); mean = new QLabel(this);
mean->setNum(0.00); mean->setNum(0.00);
mean->setStyleSheet(QString("QLabel {font-family:\"Courier\"; font-weight: bold;}")); mean->setStyleSheet(QString("QLabel {font-family:\"Courier\"; font-weight: bold;}"));
mean->setToolTip(tr("Arithmetic mean of ") + curve); mean->setToolTip(tr("Arithmetic mean of %1 in %2 units").arg(curve, unit));
mean->setWhatsThis(tr("Arithmetic mean of ") + curve); mean->setWhatsThis(tr("Arithmetic mean of %1 in %2 units").arg(curve, unit));
curveMeans->insert(curve+unit, mean); curveMeans->insert(curve+unit, mean);
curvesWidgetLayout->addWidget(mean, labelRow, 5); curvesWidgetLayout->addWidget(mean, labelRow, 5);
...@@ -627,8 +633,8 @@ void LinechartWidget::addCurve(const QString& curve, const QString& unit) ...@@ -627,8 +633,8 @@ void LinechartWidget::addCurve(const QString& curve, const QString& unit)
variance = new QLabel(this); variance = new QLabel(this);
variance->setNum(0.00); variance->setNum(0.00);
variance->setStyleSheet(QString("QLabel {font-family:\"Courier\"; font-weight: bold;}")); variance->setStyleSheet(QString("QLabel {font-family:\"Courier\"; font-weight: bold;}"));
variance->setToolTip(tr("Variance of ") + curve); variance->setToolTip(tr("Variance of %1 in (%2)^2 units").arg(curve, unit));
variance->setWhatsThis(tr("Variance of ") + curve); variance->setWhatsThis(tr("Variance of %1 in (%2)^2 units").arg(curve, unit));
curveVariances->insert(curve+unit, variance); curveVariances->insert(curve+unit, variance);
curvesWidgetLayout->addWidget(variance, labelRow, 6); curvesWidgetLayout->addWidget(variance, labelRow, 6);
......
...@@ -132,6 +132,7 @@ protected: ...@@ -132,6 +132,7 @@ protected:
QToolButton* scalingLinearButton; QToolButton* scalingLinearButton;
QToolButton* scalingLogButton; QToolButton* scalingLogButton;
QToolButton* logButton; QToolButton* logButton;
QPointer<QCheckBox> unitsCheckBox;
QFile* logFile; QFile* logFile;
unsigned int logindex; unsigned int logindex;
......
...@@ -84,6 +84,8 @@ engineOn(false) ...@@ -84,6 +84,8 @@ engineOn(false)
connect(ui.setModeButton, SIGNAL(clicked()), this, SLOT(transmitMode())); connect(ui.setModeButton, SIGNAL(clicked()), this, SLOT(transmitMode()));
ui.modeComboBox->setCurrentIndex(0); ui.modeComboBox->setCurrentIndex(0);
ui.gridLayout->setAlignment(Qt::AlignTop);
} }
void UASControlWidget::setUAS(UASInterface* uas) void UASControlWidget::setUAS(UASInterface* uas)
......
...@@ -52,6 +52,7 @@ UASListWidget::UASListWidget(QWidget *parent) : QWidget(parent), m_ui(new Ui::UA ...@@ -52,6 +52,7 @@ UASListWidget::UASListWidget(QWidget *parent) : QWidget(parent), m_ui(new Ui::UA
listLayout = new QVBoxLayout(this); listLayout = new QVBoxLayout(this);
listLayout->setAlignment(Qt::AlignTop); listLayout->setAlignment(Qt::AlignTop);
this->setLayout(listLayout); this->setLayout(listLayout);
setObjectName("UNMANNED_SYSTEMS_LIST");
// Construct initial widget // Construct initial widget
uWidget = new QGCUnconnectedInfoWidget(this); 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