Commit bfae98b7 authored by Thomas Gubler's avatar Thomas Gubler

Merge remote-tracking branch 'upstream/master' into fgfsrate

parents db2d6f72 323d162e
...@@ -416,9 +416,10 @@ contains(DEFINES, DISABLE_3DMOUSE) { ...@@ -416,9 +416,10 @@ contains(DEFINES, DISABLE_3DMOUSE) {
exists(/usr/local/lib/libxdrvlib.so) { exists(/usr/local/lib/libxdrvlib.so) {
message("Including support for 3DConnexion mice") message("Including support for 3DConnexion mice")
DEFINES += DEFINES += \
QGC_MOUSE_ENABLED_LINUX \ QGC_MOUSE_ENABLED_LINUX \
ParameterCheck # Hack: Has to be defined for magellan usage ParameterCheck
# Hack: Has to be defined for magellan usage
HEADERS += src/input/Mouse6dofInput.h HEADERS += src/input/Mouse6dofInput.h
SOURCES += src/input/Mouse6dofInput.cpp SOURCES += src/input/Mouse6dofInput.cpp
......
...@@ -187,7 +187,6 @@ DebugBuild { ...@@ -187,7 +187,6 @@ DebugBuild {
src/qgcunittest/MockUAS.h \ src/qgcunittest/MockUAS.h \
src/qgcunittest/MockQGCUASParamManager.h \ src/qgcunittest/MockQGCUASParamManager.h \
src/qgcunittest/MultiSignalSpy.h \ src/qgcunittest/MultiSignalSpy.h \
src/qgcunittest/TCPLinkTest.h \
src/qgcunittest/FlightModeConfigTest.h src/qgcunittest/FlightModeConfigTest.h
SOURCES += \ SOURCES += \
...@@ -196,7 +195,6 @@ DebugBuild { ...@@ -196,7 +195,6 @@ DebugBuild {
src/qgcunittest/MockUAS.cc \ src/qgcunittest/MockUAS.cc \
src/qgcunittest/MockQGCUASParamManager.cc \ src/qgcunittest/MockQGCUASParamManager.cc \
src/qgcunittest/MultiSignalSpy.cc \ src/qgcunittest/MultiSignalSpy.cc \
src/qgcunittest/TCPLinkTest.cc \
src/qgcunittest/FlightModeConfigTest.cc src/qgcunittest/FlightModeConfigTest.cc
} }
...@@ -562,7 +560,9 @@ HEADERS += \ ...@@ -562,7 +560,9 @@ HEADERS += \
src/ui/designer/QGCXYPlot.h \ src/ui/designer/QGCXYPlot.h \
src/ui/menuactionhelper.h \ src/ui/menuactionhelper.h \
src/uas/UASManagerInterface.h \ src/uas/UASManagerInterface.h \
src/uas/QGCUASParamManagerInterface.h src/uas/QGCUASParamManagerInterface.h \
src/uas/QGCUASWorker.h \
src/CmdLineOptParser.h
SOURCES += \ SOURCES += \
src/main.cc \ src/main.cc \
...@@ -745,4 +745,6 @@ SOURCES += \ ...@@ -745,4 +745,6 @@ SOURCES += \
src/ui/px4_configuration/QGCPX4MulticopterConfig.cc \ src/ui/px4_configuration/QGCPX4MulticopterConfig.cc \
src/ui/px4_configuration/QGCPX4SensorCalibration.cc \ src/ui/px4_configuration/QGCPX4SensorCalibration.cc \
src/ui/designer/QGCXYPlot.cc \ src/ui/designer/QGCXYPlot.cc \
src/ui/menuactionhelper.cpp src/ui/menuactionhelper.cpp \
src/uas/QGCUASWorker.cc \
src/CmdLineOptParser.cc
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @brief Command line option parser
///
/// @author Don Gagne <don@thegagnes.com>
#include "CmdLineOptParser.h"
#include <QString>
/// @brief Implements a simple command line parser which sets booleans to true if the option is found.
void ParseCmdLineOptions(int& argc, ///< count of arguments in argv
char* argv[], ///< command line arguments
CmdLineOpt_t* prgOpts, ///< command line options
size_t cOpts, ///< count of command line options
bool removeParsedOptions) ///< true: remove parsed option from argc/argv
{
// Start with all options off
for (size_t iOption=0; iOption<cOpts; iOption++) {
*prgOpts[iOption].flag = false;
}
for (int iArg=1; iArg<argc; iArg++) {
for (size_t iOption=0; iOption<cOpts; iOption++) {
if (QString(argv[iArg]).compare(prgOpts[iOption].optionStr, Qt::CaseInsensitive) == 0) {
*prgOpts[iOption].flag = true;
if (removeParsedOptions) {
for (int iShift=iArg; iShift<argc-1; iShift++) {
argv[iShift] = argv[iShift+1];
}
argc--;
iArg--;
}
}
}
}
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @brief Command line option parser
///
/// @author Don Gagne <don@thegagnes.com>
#ifndef CMDLINEOPTPARSER_H
#define CMDLINEOPTPARSER_H
#include <cstring>
/// @brief Structure used to pass command line options to the ParseCmdLineOptions function.
typedef struct {
const char* optionStr; ///< command line option, for example "--foo"
bool* flag; ///< if option is found this variable will be set to true
} CmdLineOpt_t;
void ParseCmdLineOptions(int& argc,
char* argv[],
CmdLineOpt_t* prgOpts,
size_t cOpts,
bool removeParsedOptions);
#endif
...@@ -47,6 +47,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -47,6 +47,7 @@ This file is part of the QGROUNDCONTROL project
#include "MainWindow.h" #include "MainWindow.h"
#include "QGCWelcomeMainWindow.h" #include "QGCWelcomeMainWindow.h"
#include "GAudioOutput.h" #include "GAudioOutput.h"
#include "CmdLineOptParser.h"
#ifdef QGC_RTLAB_ENABLED #ifdef QGC_RTLAB_ENABLED
#include "OpalLink.h" #include "OpalLink.h"
...@@ -83,11 +84,24 @@ QGCCore::QGCCore(bool firstStart, int &argc, char* argv[]) : QApplication(argc, ...@@ -83,11 +84,24 @@ QGCCore::QGCCore(bool firstStart, int &argc, char* argv[]) : QApplication(argc,
// Set settings format // Set settings format
QSettings::setDefaultFormat(QSettings::IniFormat); QSettings::setDefaultFormat(QSettings::IniFormat);
// Check application settings // Parse command line options
// clear them if they mismatch
// QGC then falls back to default bool fClearSettingsOptions = false; // Clear stored settings
CmdLineOpt_t rgCmdLineOptions[] = {
{ "--clear-settings", &fClearSettingsOptions },
// Add additional command line option flags here
};
ParseCmdLineOptions(argc, argv, rgCmdLineOptions, sizeof(rgCmdLineOptions)/sizeof(rgCmdLineOptions[0]), false);
QSettings settings; QSettings settings;
if (fClearSettingsOptions) {
// User requested settings to be cleared on command line
settings.clear();
}
// Show user an upgrade message if QGC got upgraded (see code below, after splash screen) // Show user an upgrade message if QGC got upgraded (see code below, after splash screen)
bool upgraded = false; bool upgraded = false;
enum MainWindow::CUSTOM_MODE mode = MainWindow::CUSTOM_MODE_NONE; enum MainWindow::CUSTOM_MODE mode = MainWindow::CUSTOM_MODE_NONE;
...@@ -98,7 +112,7 @@ QGCCore::QGCCore(bool firstStart, int &argc, char* argv[]) : QApplication(argc, ...@@ -98,7 +112,7 @@ QGCCore::QGCCore(bool firstStart, int &argc, char* argv[]) : QApplication(argc,
if (qgcVersion != QGC_APPLICATION_VERSION) if (qgcVersion != QGC_APPLICATION_VERSION)
{ {
lastApplicationVersion = qgcVersion; lastApplicationVersion = qgcVersion;
settings.clear(); settings.clear(); // Clear settings from different version
// Write current application version // Write current application version
settings.setValue("QGC_APPLICATION_VERSION", QGC_APPLICATION_VERSION); settings.setValue("QGC_APPLICATION_VERSION", QGC_APPLICATION_VERSION);
upgraded = true; upgraded = true;
......
...@@ -36,6 +36,7 @@ along with PIXHAWK. If not, see <http://www.gnu.org/licenses/>. ...@@ -36,6 +36,7 @@ along with PIXHAWK. If not, see <http://www.gnu.org/licenses/>.
#include <QDateTime> #include <QDateTime>
#include <QMutex> #include <QMutex>
#include <QMutexLocker> #include <QMutexLocker>
#include <QMetaType>
/** /**
* The link interface defines the interface for all links used to communicate * The link interface defines the interface for all links used to communicate
...@@ -62,6 +63,7 @@ public: ...@@ -62,6 +63,7 @@ public:
outDataWriteTimes[i] = 0; outDataWriteTimes[i] = 0;
} }
qRegisterMetaType<LinkInterface*>("LinkInterface*");
} }
virtual ~LinkInterface() { virtual ~LinkInterface() {
......
...@@ -44,7 +44,7 @@ Q_DECLARE_METATYPE(mavlink_message_t) ...@@ -44,7 +44,7 @@ Q_DECLARE_METATYPE(mavlink_message_t)
* the MAVLINK_HEARTBEAT_DEFAULT_RATE to all connected links. * the MAVLINK_HEARTBEAT_DEFAULT_RATE to all connected links.
*/ */
MAVLinkProtocol::MAVLinkProtocol() : MAVLinkProtocol::MAVLinkProtocol() :
heartbeatTimer(), heartbeatTimer(NULL),
heartbeatRate(MAVLINK_HEARTBEAT_DEFAULT_RATE), heartbeatRate(MAVLINK_HEARTBEAT_DEFAULT_RATE),
m_heartbeatsEnabled(true), m_heartbeatsEnabled(true),
m_multiplexingEnabled(false), m_multiplexingEnabled(false),
...@@ -58,17 +58,14 @@ MAVLinkProtocol::MAVLinkProtocol() : ...@@ -58,17 +58,14 @@ MAVLinkProtocol::MAVLinkProtocol() :
m_actionGuardEnabled(false), m_actionGuardEnabled(false),
m_actionRetransmissionTimeout(100), m_actionRetransmissionTimeout(100),
versionMismatchIgnore(false), versionMismatchIgnore(false),
systemId(QGC::defaultSystemId) systemId(QGC::defaultSystemId),
_should_exit(false)
{ {
qRegisterMetaType<mavlink_message_t>("mavlink_message_t"); qRegisterMetaType<mavlink_message_t>("mavlink_message_t");
m_authKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; m_authKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
loadSettings(); loadSettings();
moveToThread(this); moveToThread(this);
heartbeatTimer.moveToThread(this);
// Start heartbeat timer, emitting a heartbeat at the configured rate
connect(&heartbeatTimer, SIGNAL(timeout()), this, SLOT(sendHeartbeat()));
heartbeatTimer.start(1000/heartbeatRate);
// All the *Counter variables are not initialized here, as they should be initialized // All the *Counter variables are not initialized here, as they should be initialized
// on a per-link basis before those links are used. @see resetMetadataForLink(). // on a per-link basis before those links are used. @see resetMetadataForLink().
...@@ -171,7 +168,7 @@ MAVLinkProtocol::~MAVLinkProtocol() ...@@ -171,7 +168,7 @@ MAVLinkProtocol::~MAVLinkProtocol()
} }
// Tell the thread to exit // Tell the thread to exit
quit(); _should_exit = true;
// Wait for it to exit // Wait for it to exit
wait(); wait();
} }
...@@ -182,7 +179,22 @@ MAVLinkProtocol::~MAVLinkProtocol() ...@@ -182,7 +179,22 @@ MAVLinkProtocol::~MAVLinkProtocol()
**/ **/
void MAVLinkProtocol::run() void MAVLinkProtocol::run()
{ {
exec(); heartbeatTimer = new QTimer();
heartbeatTimer->moveToThread(this);
// Start heartbeat timer, emitting a heartbeat at the configured rate
connect(heartbeatTimer, SIGNAL(timeout()), this, SLOT(sendHeartbeat()));
heartbeatTimer->start(1000/heartbeatRate);
while(!_should_exit) {
if (isFinished()) {
qDebug() << "MAVLINK WORKER DONE!";
return;
}
QCoreApplication::processEvents();
QGC::SLEEP::msleep(2);
}
} }
QString MAVLinkProtocol::getLogfileName() QString MAVLinkProtocol::getLogfileName()
...@@ -782,7 +794,7 @@ void MAVLinkProtocol::enableVersionCheck(bool enabled) ...@@ -782,7 +794,7 @@ void MAVLinkProtocol::enableVersionCheck(bool enabled)
void MAVLinkProtocol::setHeartbeatRate(int rate) void MAVLinkProtocol::setHeartbeatRate(int rate)
{ {
heartbeatRate = rate; heartbeatRate = rate;
heartbeatTimer.setInterval(1000/heartbeatRate); heartbeatTimer->setInterval(1000/heartbeatRate);
} }
/** @return heartbeat rate in Hertz */ /** @return heartbeat rate in Hertz */
......
...@@ -214,7 +214,7 @@ public slots: ...@@ -214,7 +214,7 @@ public slots:
void storeSettings(); void storeSettings();
protected: protected:
QTimer heartbeatTimer; ///< Timer to emit heartbeats QTimer *heartbeatTimer; ///< Timer to emit heartbeats
int heartbeatRate; ///< Heartbeat rate, controls the timer interval int heartbeatRate; ///< Heartbeat rate, controls the timer interval
bool m_heartbeatsEnabled; ///< Enabled/disable heartbeat emission bool m_heartbeatsEnabled; ///< Enabled/disable heartbeat emission
bool m_multiplexingEnabled; ///< Enable/disable packet multiplexing bool m_multiplexingEnabled; ///< Enable/disable packet multiplexing
...@@ -237,6 +237,8 @@ protected: ...@@ -237,6 +237,8 @@ protected:
int currLossCounter[MAVLINK_COMM_NUM_BUFFERS]; ///< Lost messages during this sample time window. Used for calculating loss %. int currLossCounter[MAVLINK_COMM_NUM_BUFFERS]; ///< Lost messages during this sample time window. Used for calculating loss %.
bool versionMismatchIgnore; bool versionMismatchIgnore;
int systemId; int systemId;
bool _should_exit;
#if defined(QGC_PROTOBUF_ENABLED) && defined(QGC_USE_PIXHAWK_MESSAGES) #if defined(QGC_PROTOBUF_ENABLED) && defined(QGC_USE_PIXHAWK_MESSAGES)
mavlink::ProtobufManager protobufManager; mavlink::ProtobufManager protobufManager;
#endif #endif
......
...@@ -57,7 +57,8 @@ QGCXPlaneLink::QGCXPlaneLink(UASInterface* mav, QString remoteHost, QHostAddress ...@@ -57,7 +57,8 @@ QGCXPlaneLink::QGCXPlaneLink(UASInterface* mav, QString remoteHost, QHostAddress
simUpdateLastText(QGC::groundTimeMilliseconds()), simUpdateLastText(QGC::groundTimeMilliseconds()),
simUpdateLastGroundTruth(QGC::groundTimeMilliseconds()), simUpdateLastGroundTruth(QGC::groundTimeMilliseconds()),
simUpdateHz(0), simUpdateHz(0),
_sensorHilEnabled(true) _sensorHilEnabled(true),
_should_exit(false)
{ {
// We're doing it wrong - because the Qt folks got the API wrong: // We're doing it wrong - because the Qt folks got the API wrong:
// http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/ // http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/
...@@ -75,7 +76,7 @@ QGCXPlaneLink::~QGCXPlaneLink() ...@@ -75,7 +76,7 @@ QGCXPlaneLink::~QGCXPlaneLink()
{ {
storeSettings(); storeSettings();
// Tell the thread to exit // Tell the thread to exit
quit(); _should_exit = true;
// Wait for it to exit // Wait for it to exit
wait(); wait();
...@@ -216,7 +217,10 @@ void QGCXPlaneLink::run() ...@@ -216,7 +217,10 @@ void QGCXPlaneLink::run()
writeBytes((const char*)&ip, sizeof(ip)); writeBytes((const char*)&ip, sizeof(ip));
exec(); while(!_should_exit) {
QCoreApplication::processEvents();
QGC::SLEEP::msleep(5);
}
} }
void QGCXPlaneLink::setPort(int localPort) void QGCXPlaneLink::setPort(int localPort)
......
...@@ -210,6 +210,7 @@ protected: ...@@ -210,6 +210,7 @@ protected:
quint64 simUpdateLastGroundTruth; quint64 simUpdateLastGroundTruth;
float simUpdateHz; float simUpdateHz;
bool _sensorHilEnabled; bool _sensorHilEnabled;
bool _should_exit;
void setName(QString name); void setName(QString name);
}; };
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <QString> #include <QString>
/** @brief Polling interval in ms */ /** @brief Polling interval in ms */
#define SERIAL_POLL_INTERVAL 5 #define SERIAL_POLL_INTERVAL 4
/** @brief Heartbeat emission rate, in Hertz (times per second) */ /** @brief Heartbeat emission rate, in Hertz (times per second) */
#define MAVLINK_HEARTBEAT_DEFAULT_RATE 1 #define MAVLINK_HEARTBEAT_DEFAULT_RATE 1
......
...@@ -36,6 +36,10 @@ This file is part of the QGROUNDCONTROL project ...@@ -36,6 +36,10 @@ This file is part of the QGROUNDCONTROL project
#include "TCPLink.h" #include "TCPLink.h"
#ifdef QT_DEBUG #ifdef QT_DEBUG
#include "AutoTest.h" #include "AutoTest.h"
#include "CmdLineOptParser.h"
#ifdef Q_OS_WIN
#include <crtdbg.h>
#endif
#endif #endif
/* SDL does ugly things to main() */ /* SDL does ugly things to main() */
...@@ -44,10 +48,10 @@ This file is part of the QGROUNDCONTROL project ...@@ -44,10 +48,10 @@ This file is part of the QGROUNDCONTROL project
#endif #endif
// Install a message handler so you do not need
// the MSFT debug tools installed to se
// qDebug(), qWarning(), qCritical and qAbort
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
/// @brief Message handler which is installed using qInstallMsgHandler so you do not need
/// the MSFT debug tools installed to see qDebug(), qWarning(), qCritical and qAbort
void msgHandler( QtMsgType type, const char* msg ) void msgHandler( QtMsgType type, const char* msg )
{ {
const char symbols[] = { 'I', 'E', '!', 'X' }; const char symbols[] = { 'I', 'E', '!', 'X' };
...@@ -56,6 +60,17 @@ void msgHandler( QtMsgType type, const char* msg ) ...@@ -56,6 +60,17 @@ void msgHandler( QtMsgType type, const char* msg )
if( type == QtFatalMsg ) abort(); if( type == QtFatalMsg ) abort();
} }
/// @brief CRT Report Hook installed using _CrtSetReportHook. We install this hook when
/// we don't want asserts to pop a dialog on windows.
int WindowsCrtReportHook(int reportType, char* message, int* returnValue)
{
Q_UNUSED(reportType);
std::cerr << message << std::endl; // Output message to stderr
*returnValue = 0; // Don't break into debugger
return true; // We handled this fully ourselves
}
#endif #endif
/** /**
...@@ -81,13 +96,27 @@ int main(int argc, char *argv[]) ...@@ -81,13 +96,27 @@ int main(int argc, char *argv[])
qRegisterMetaType<QAbstractSocket::SocketError>(); qRegisterMetaType<QAbstractSocket::SocketError>();
#ifdef QT_DEBUG #ifdef QT_DEBUG
if (argc > 1 && QString(argv[1]).compare("--unittest", Qt::CaseInsensitive) == 0) { // We parse a small set of command line options here prior to QGCCore in order to handle the ones
// Strip off extra command line args so QTest doesn't complain // which need to be handled before a QApplication object is started.
for (int i=1; i<argc-1; i++)
{ bool runUnitTests = false; // Run unit test
argv[i] = argv[i+1]; bool quietWindowsAsserts = false; // Don't let asserts pop dialog boxes
CmdLineOpt_t rgCmdLineOptions[] = {
{ "--unittest", &runUnitTests },
{ "--no-windows-assert-ui", &quietWindowsAsserts },
// Add additional command line option flags here
};
ParseCmdLineOptions(argc, argv, rgCmdLineOptions, sizeof(rgCmdLineOptions)/sizeof(rgCmdLineOptions[0]), true);
if (quietWindowsAsserts) {
#ifdef Q_OS_WIN
_CrtSetReportHook(WindowsCrtReportHook);
#endif
} }
if (runUnitTests) {
// Run the test // Run the test
int failures = AutoTest::run(argc-1, argv); int failures = AutoTest::run(argc-1, argv);
if (failures == 0) if (failures == 0)
......
#include "UASUnitTest.h" #include "UASUnitTest.h"
#include <stdio.h> #include <stdio.h>
#include <QObject> #include <QObject>
#include <QThread>
UASUnitTest::UASUnitTest() UASUnitTest::UASUnitTest()
{ {
} }
...@@ -8,7 +10,7 @@ UASUnitTest::UASUnitTest() ...@@ -8,7 +10,7 @@ UASUnitTest::UASUnitTest()
void UASUnitTest::init() void UASUnitTest::init()
{ {
mav = new MAVLinkProtocol(); mav = new MAVLinkProtocol();
uas = new UAS(mav, UASID); uas = new UAS(mav, QThread::currentThread(), UASID);
uas->deleteSettings(); uas->deleteSettings();
} }
//this function is called after every test //this function is called after every test
...@@ -24,7 +26,7 @@ void UASUnitTest::cleanup() ...@@ -24,7 +26,7 @@ void UASUnitTest::cleanup()
void UASUnitTest::getUASID_test() void UASUnitTest::getUASID_test()
{ {
// Test a default ID of zero is assigned // Test a default ID of zero is assigned
UAS* uas2 = new UAS(mav); UAS* uas2 = new UAS(mav, QThread::currentThread());
QCOMPARE(uas2->getUASID(), 0); QCOMPARE(uas2->getUASID(), 0);
delete uas2; delete uas2;
...@@ -49,7 +51,7 @@ void UASUnitTest::getUASName_test() ...@@ -49,7 +51,7 @@ void UASUnitTest::getUASName_test()
void UASUnitTest::getUpTime_test() void UASUnitTest::getUpTime_test()
{ {
UAS* uas2 = new UAS(mav); UAS* uas2 = new UAS(mav, QThread::currentThread());
// Test that the uptime starts at zero to a // Test that the uptime starts at zero to a
// precision of seconds // precision of seconds
QCOMPARE(floor(uas2->getUptime()/1000.0), 0.0); QCOMPARE(floor(uas2->getUptime()/1000.0), 0.0);
...@@ -281,7 +283,7 @@ void UASUnitTest::signalWayPoint_test() ...@@ -281,7 +283,7 @@ void UASUnitTest::signalWayPoint_test()
delete uas;// delete(destroyed) uas for validating delete uas;// delete(destroyed) uas for validating
uas = NULL; uas = NULL;
QCOMPARE(spyDestroyed.count(), 1);// count destroyed uas should are 1 QCOMPARE(spyDestroyed.count(), 1);// count destroyed uas should are 1
uas = new UAS(mav,UASID); uas = new UAS(mav, QThread::currentThread(), UASID);
QSignalSpy spy2(uas->getWaypointManager(), SIGNAL(waypointEditableListChanged())); QSignalSpy spy2(uas->getWaypointManager(), SIGNAL(waypointEditableListChanged()));
QCOMPARE(spy2.count(), 0); QCOMPARE(spy2.count(), 0);
Waypoint* wp2 = new Waypoint(0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,false, false, MAV_FRAME_GLOBAL, MAV_CMD_MISSION_START, "blah"); Waypoint* wp2 = new Waypoint(0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,false, false, MAV_FRAME_GLOBAL, MAV_CMD_MISSION_START, "blah");
......
#include "QGCMAVLinkUASFactory.h" #include "QGCMAVLinkUASFactory.h"
#include "UASManager.h" #include "UASManager.h"
#include "QGCUASWorker.h"
QGCMAVLinkUASFactory::QGCMAVLinkUASFactory(QObject *parent) : QGCMAVLinkUASFactory::QGCMAVLinkUASFactory(QObject *parent) :
QObject(parent) QObject(parent)
...@@ -21,7 +22,7 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte ...@@ -21,7 +22,7 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte
UASInterface* uas; UASInterface* uas;
QThread* worker = new QThread(); QGCUASWorker* worker = new QGCUASWorker();
switch (heartbeat->autopilot) switch (heartbeat->autopilot)
{ {
...@@ -31,8 +32,6 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte ...@@ -31,8 +32,6 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte
// Set the system type // Set the system type
mav->setSystemType((int)heartbeat->type); mav->setSystemType((int)heartbeat->type);
mav->moveToThread(worker);
// Connect this robot to the UAS object // Connect this robot to the UAS object
connect(mavlink, SIGNAL(messageReceived(LinkInterface*, mavlink_message_t)), mav, SLOT(receiveMessage(LinkInterface*, mavlink_message_t))); connect(mavlink, SIGNAL(messageReceived(LinkInterface*, mavlink_message_t)), mav, SLOT(receiveMessage(LinkInterface*, mavlink_message_t)));
#ifdef QGC_PROTOBUF_ENABLED #ifdef QGC_PROTOBUF_ENABLED
...@@ -47,8 +46,6 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte ...@@ -47,8 +46,6 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte
// Set the system type // Set the system type
mav->setSystemType((int)heartbeat->type); mav->setSystemType((int)heartbeat->type);
mav->moveToThread(worker);
// Connect this robot to the UAS object // Connect this robot to the UAS object
// it is IMPORTANT here to use the right object type, // it is IMPORTANT here to use the right object type,
// else the slot of the parent object is called (and thus the special // else the slot of the parent object is called (and thus the special
...@@ -66,8 +63,6 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte ...@@ -66,8 +63,6 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte
// Set the system type // Set the system type
mav->setSystemType((int)heartbeat->type); mav->setSystemType((int)heartbeat->type);
mav->moveToThread(worker);
// Connect this robot to the UAS object // Connect this robot to the UAS object
// it is IMPORTANT here to use the right object type, // it is IMPORTANT here to use the right object type,
// else the slot of the parent object is called (and thus the special // else the slot of the parent object is called (and thus the special
...@@ -82,8 +77,6 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte ...@@ -82,8 +77,6 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte
// Set the system type // Set the system type
mav->setSystemType((int)heartbeat->type); mav->setSystemType((int)heartbeat->type);
mav->moveToThread(worker);
// Connect this robot to the UAS object // Connect this robot to the UAS object
// it is IMPORTANT here to use the right object type, // it is IMPORTANT here to use the right object type,
// else the slot of the parent object is called (and thus the special // else the slot of the parent object is called (and thus the special
...@@ -120,6 +113,10 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte ...@@ -120,6 +113,10 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte
break; break;
} }
// Get the UAS ready
worker->start(QThread::HighPriority);
connect(uas, SIGNAL(destroyed()), worker, SLOT(quit()));
// Set the autopilot type // Set the autopilot type
uas->setAutopilotType((int)heartbeat->autopilot); uas->setAutopilotType((int)heartbeat->autopilot);
...@@ -129,8 +126,5 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte ...@@ -129,8 +126,5 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte
// Now add UAS to "official" list, which makes the whole application aware of it // Now add UAS to "official" list, which makes the whole application aware of it
UASManager::instance()->addUAS(uas); UASManager::instance()->addUAS(uas);
worker->start(QThread::HighPriority);
connect(uas, SIGNAL(destroyed()), worker, SLOT(quit()));
return uas; return uas;
} }
#include "QGCUASWorker.h"
#include <QGC.h>
#include <QCoreApplication>
#include <QDebug>
QGCUASWorker::QGCUASWorker() : QThread(),
_should_exit(false)
{
}
void QGCUASWorker::quit()
{
_should_exit = true;
}
void QGCUASWorker::run()
{
while(!_should_exit) {
QCoreApplication::processEvents();
QGC::SLEEP::msleep(2);
}
}
#ifndef QGCUASWORKER_H
#define QGCUASWORKER_H
#include <QThread>
class QGCUASWorker : public QThread
{
public:
QGCUASWorker();
public slots:
void quit();
protected:
void run();
bool _should_exit;
};
#endif // QGCUASWORKER_H
...@@ -51,7 +51,7 @@ UAS::UAS(MAVLinkProtocol* protocol, QThread* thread, int id) : UASInterface(), ...@@ -51,7 +51,7 @@ UAS::UAS(MAVLinkProtocol* protocol, QThread* thread, int id) : UASInterface(),
commStatus(COMM_DISCONNECTED), commStatus(COMM_DISCONNECTED),
receiveDropRate(0), receiveDropRate(0),
sendDropRate(0), sendDropRate(0),
statusTimeout(new QTimer(this)), statusTimeout(thread),
name(""), name(""),
type(MAV_TYPE_GENERIC), type(MAV_TYPE_GENERIC),
...@@ -155,6 +155,7 @@ UAS::UAS(MAVLinkProtocol* protocol, QThread* thread, int id) : UASInterface(), ...@@ -155,6 +155,7 @@ UAS::UAS(MAVLinkProtocol* protocol, QThread* thread, int id) : UASInterface(),
paramsOnceRequested(false), paramsOnceRequested(false),
paramMgr(this), paramMgr(this),
simulation(0), simulation(0),
_thread(thread),
// The protected members. // The protected members.
connectionLost(false), connectionLost(false),
...@@ -167,9 +168,6 @@ UAS::UAS(MAVLinkProtocol* protocol, QThread* thread, int id) : UASInterface(), ...@@ -167,9 +168,6 @@ UAS::UAS(MAVLinkProtocol* protocol, QThread* thread, int id) : UASInterface(),
lastSendTimeSensors(0) lastSendTimeSensors(0)
{ {
moveToThread(thread); moveToThread(thread);
waypointManager.moveToThread(thread);
paramMgr.moveToThread(thread);
statusTimeout->moveToThread(thread);
for (unsigned int i = 0; i<255;++i) for (unsigned int i = 0; i<255;++i)
{ {
...@@ -180,66 +178,66 @@ UAS::UAS(MAVLinkProtocol* protocol, QThread* thread, int id) : UASInterface(), ...@@ -180,66 +178,66 @@ UAS::UAS(MAVLinkProtocol* protocol, QThread* thread, int id) : UASInterface(),
// Store a list of available actions for this UAS. // Store a list of available actions for this UAS.
// Basically everything exposed as a SLOT with no return value or arguments. // Basically everything exposed as a SLOT with no return value or arguments.
QAction* newAction = new QAction(tr("Arm"), this); QAction* newAction = new QAction(tr("Arm"), thread);
newAction->setToolTip(tr("Enable the UAS so that all actuators are online")); newAction->setToolTip(tr("Enable the UAS so that all actuators are online"));
connect(newAction, SIGNAL(triggered()), this, SLOT(armSystem())); connect(newAction, SIGNAL(triggered()), this, SLOT(armSystem()));
actions.append(newAction); actions.append(newAction);
newAction = new QAction(tr("Disarm"), this); newAction = new QAction(tr("Disarm"), thread);
newAction->setToolTip(tr("Disable the UAS so that all actuators are offline")); newAction->setToolTip(tr("Disable the UAS so that all actuators are offline"));
connect(newAction, SIGNAL(triggered()), this, SLOT(disarmSystem())); connect(newAction, SIGNAL(triggered()), this, SLOT(disarmSystem()));
actions.append(newAction); actions.append(newAction);
newAction = new QAction(tr("Toggle armed"), this); newAction = new QAction(tr("Toggle armed"), thread);
newAction->setToolTip(tr("Toggle between armed and disarmed")); newAction->setToolTip(tr("Toggle between armed and disarmed"));
connect(newAction, SIGNAL(triggered()), this, SLOT(toggleAutonomy())); connect(newAction, SIGNAL(triggered()), this, SLOT(toggleAutonomy()));
actions.append(newAction); actions.append(newAction);
newAction = new QAction(tr("Go home"), this); newAction = new QAction(tr("Go home"), thread);
newAction->setToolTip(tr("Command the UAS to return to its home position")); newAction->setToolTip(tr("Command the UAS to return to its home position"));
connect(newAction, SIGNAL(triggered()), this, SLOT(home())); connect(newAction, SIGNAL(triggered()), this, SLOT(home()));
actions.append(newAction); actions.append(newAction);
newAction = new QAction(tr("Land"), this); newAction = new QAction(tr("Land"), thread);
newAction->setToolTip(tr("Command the UAS to land")); newAction->setToolTip(tr("Command the UAS to land"));
connect(newAction, SIGNAL(triggered()), this, SLOT(land())); connect(newAction, SIGNAL(triggered()), this, SLOT(land()));
actions.append(newAction); actions.append(newAction);
newAction = new QAction(tr("Launch"), this); newAction = new QAction(tr("Launch"), thread);
newAction->setToolTip(tr("Command the UAS to launch itself and begin its mission")); newAction->setToolTip(tr("Command the UAS to launch itself and begin its mission"));
connect(newAction, SIGNAL(triggered()), this, SLOT(launch())); connect(newAction, SIGNAL(triggered()), this, SLOT(launch()));
actions.append(newAction); actions.append(newAction);
newAction = new QAction(tr("Resume"), this); newAction = new QAction(tr("Resume"), thread);
newAction->setToolTip(tr("Command the UAS to continue its mission")); newAction->setToolTip(tr("Command the UAS to continue its mission"));
connect(newAction, SIGNAL(triggered()), this, SLOT(go())); connect(newAction, SIGNAL(triggered()), this, SLOT(go()));
actions.append(newAction); actions.append(newAction);
newAction = new QAction(tr("Stop"), this); newAction = new QAction(tr("Stop"), thread);
newAction->setToolTip(tr("Command the UAS to halt and hold position")); newAction->setToolTip(tr("Command the UAS to halt and hold position"));
connect(newAction, SIGNAL(triggered()), this, SLOT(halt())); connect(newAction, SIGNAL(triggered()), this, SLOT(halt()));
actions.append(newAction); actions.append(newAction);
newAction = new QAction(tr("Go autonomous"), this); newAction = new QAction(tr("Go autonomous"), thread);
newAction->setToolTip(tr("Set the UAS into an autonomous control mode")); newAction->setToolTip(tr("Set the UAS into an autonomous control mode"));
connect(newAction, SIGNAL(triggered()), this, SLOT(goAutonomous())); connect(newAction, SIGNAL(triggered()), this, SLOT(goAutonomous()));
actions.append(newAction); actions.append(newAction);
newAction = new QAction(tr("Go manual"), this); newAction = new QAction(tr("Go manual"), thread);
newAction->setToolTip(tr("Set the UAS into a manual control mode")); newAction->setToolTip(tr("Set the UAS into a manual control mode"));
connect(newAction, SIGNAL(triggered()), this, SLOT(goManual())); connect(newAction, SIGNAL(triggered()), this, SLOT(goManual()));
actions.append(newAction); actions.append(newAction);
newAction = new QAction(tr("Toggle autonomy"), this); newAction = new QAction(tr("Toggle autonomy"), thread);
newAction->setToolTip(tr("Toggle between manual and full-autonomy")); newAction->setToolTip(tr("Toggle between manual and full-autonomy"));
connect(newAction, SIGNAL(triggered()), this, SLOT(toggleAutonomy())); connect(newAction, SIGNAL(triggered()), this, SLOT(toggleAutonomy()));
actions.append(newAction); actions.append(newAction);
color = UASInterface::getNextColor(); color = UASInterface::getNextColor();
setBatterySpecs(QString("")); setBatterySpecs(QString(""));
connect(statusTimeout, SIGNAL(timeout()), this, SLOT(updateState())); connect(&statusTimeout, SIGNAL(timeout()), this, SLOT(updateState()));
connect(this, SIGNAL(systemSpecsChanged(int)), this, SLOT(writeSettings())); connect(this, SIGNAL(systemSpecsChanged(int)), this, SLOT(writeSettings()));
statusTimeout->start(500); statusTimeout.start(500);
readSettings(); readSettings();
//need to init paramMgr after readSettings have been loaded, to properly set autopilot and so forth //need to init paramMgr after readSettings have been loaded, to properly set autopilot and so forth
paramMgr.initWithUAS(this); paramMgr.initWithUAS(this);
...@@ -255,8 +253,11 @@ UAS::UAS(MAVLinkProtocol* protocol, QThread* thread, int id) : UASInterface(), ...@@ -255,8 +253,11 @@ UAS::UAS(MAVLinkProtocol* protocol, QThread* thread, int id) : UASInterface(),
UAS::~UAS() UAS::~UAS()
{ {
writeSettings(); writeSettings();
_thread->quit();
_thread->wait();
delete links; delete links;
delete statusTimeout;
delete simulation; delete simulation;
} }
......
...@@ -382,7 +382,7 @@ protected: //COMMENTS FOR TEST UNIT ...@@ -382,7 +382,7 @@ protected: //COMMENTS FOR TEST UNIT
float receiveDropRate; ///< Percentage of packets that were dropped on the MAV's receiving link (from GCS and other MAVs) float receiveDropRate; ///< Percentage of packets that were dropped on the MAV's receiving link (from GCS and other MAVs)
float sendDropRate; ///< Percentage of packets that were not received from the MAV by the GCS float sendDropRate; ///< Percentage of packets that were not received from the MAV by the GCS
quint64 lastHeartbeat; ///< Time of the last heartbeat message quint64 lastHeartbeat; ///< Time of the last heartbeat message
QTimer* statusTimeout; ///< Timer for various status timeouts QTimer statusTimeout; ///< Timer for various status timeouts
/// BASIC UAS TYPE, NAME AND STATE /// BASIC UAS TYPE, NAME AND STATE
QString name; ///< Human-friendly name of the vehicle, e.g. bravo QString name; ///< Human-friendly name of the vehicle, e.g. bravo
...@@ -526,6 +526,7 @@ protected: //COMMENTS FOR TEST UNIT ...@@ -526,6 +526,7 @@ protected: //COMMENTS FOR TEST UNIT
/// SIMULATION /// SIMULATION
QGCHilLink* simulation; ///< Hardware in the loop simulation link QGCHilLink* simulation; ///< Hardware in the loop simulation link
QThread* _thread;
public: public:
/** @brief Set the current battery type */ /** @brief Set the current battery type */
......
...@@ -760,6 +760,7 @@ void MainWindow::loadDockWidget(const QString& name) ...@@ -760,6 +760,7 @@ void MainWindow::loadDockWidget(const QString& name)
{ {
if(menuActionHelper->containsDockWidget(currentView, name)) if(menuActionHelper->containsDockWidget(currentView, name))
return; return;
if (name.startsWith("HIL_CONFIG")) if (name.startsWith("HIL_CONFIG"))
{ {
//It's a HIL widget. //It's a HIL widget.
...@@ -826,7 +827,7 @@ void MainWindow::loadDockWidget(const QString& name) ...@@ -826,7 +827,7 @@ void MainWindow::loadDockWidget(const QString& name)
} }
else if (name == "HEAD_UP_DISPLAY_DOCKWIDGET") else if (name == "HEAD_UP_DISPLAY_DOCKWIDGET")
{ {
createDockWidget(centerStack->currentWidget(),new HUD(320,240,this),tr("Head Up Display"),"HEAD_UP_DISPLAY_DOCKWIDGET",currentView,Qt::RightDockWidgetArea); createDockWidget(centerStack->currentWidget(),new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",currentView,Qt::RightDockWidgetArea);
} }
else if (name == "UAS_INFO_QUICKVIEW_DOCKWIDGET") else if (name == "UAS_INFO_QUICKVIEW_DOCKWIDGET")
{ {
......
...@@ -110,6 +110,9 @@ const QString PrimaryFlightDisplay::compassWindNames[] = { ...@@ -110,6 +110,9 @@ const QString PrimaryFlightDisplay::compassWindNames[] = {
PrimaryFlightDisplay::PrimaryFlightDisplay(int width, int height, QWidget *parent) : PrimaryFlightDisplay::PrimaryFlightDisplay(int width, int height, QWidget *parent) :
QWidget(parent), QWidget(parent),
_valuesChanged(false),
_valuesLastPainted(QGC::groundTimeMilliseconds()),
uas(NULL), uas(NULL),
roll(0), roll(0),
...@@ -159,7 +162,7 @@ PrimaryFlightDisplay::PrimaryFlightDisplay(int width, int height, QWidget *paren ...@@ -159,7 +162,7 @@ PrimaryFlightDisplay::PrimaryFlightDisplay(int width, int height, QWidget *paren
// Refresh timer // Refresh timer
refreshTimer->setInterval(updateInterval); refreshTimer->setInterval(updateInterval);
// connect(refreshTimer, SIGNAL(timeout()), this, SLOT(paintHUD())); // connect(refreshTimer, SIGNAL(timeout()), this, SLOT(paintHUD()));
connect(refreshTimer, SIGNAL(timeout()), this, SLOT(update())); connect(refreshTimer, SIGNAL(timeout()), this, SLOT(checkUpdate()));
} }
PrimaryFlightDisplay::~PrimaryFlightDisplay() PrimaryFlightDisplay::~PrimaryFlightDisplay()
...@@ -224,6 +227,15 @@ void PrimaryFlightDisplay::paintEvent(QPaintEvent *event) ...@@ -224,6 +227,15 @@ void PrimaryFlightDisplay::paintEvent(QPaintEvent *event)
doPaint(); doPaint();
} }
void PrimaryFlightDisplay::checkUpdate()
{
if (uas && (_valuesChanged || (QGC::groundTimeMilliseconds() - _valuesLastPainted) > 260)) {
update();
_valuesChanged = false;
_valuesLastPainted = QGC::groundTimeMilliseconds();
}
}
///* ///*
// * Interface towards qgroundcontrol // * Interface towards qgroundcontrol
// */ // */
...@@ -280,24 +292,45 @@ void PrimaryFlightDisplay::updateAttitude(UASInterface* uas, double roll, double ...@@ -280,24 +292,45 @@ void PrimaryFlightDisplay::updateAttitude(UASInterface* uas, double roll, double
{ {
Q_UNUSED(uas); Q_UNUSED(uas);
Q_UNUSED(timestamp); Q_UNUSED(timestamp);
// Called from UAS.cc l. 616 // Called from UAS.cc l. 616
if (isinf(roll)) { if (isinf(roll)) {
this->roll = std::numeric_limits<double>::quiet_NaN(); this->roll = std::numeric_limits<double>::quiet_NaN();
} else { } else {
this->roll = roll * (180.0 / M_PI);
float rolldeg = roll * (180.0 / M_PI);
if (fabsf(roll - rolldeg) > 2.5f) {
_valuesChanged = true;
}
this->roll = rolldeg;
} }
if (isinf(pitch)) { if (isinf(pitch)) {
this->pitch = std::numeric_limits<double>::quiet_NaN(); this->pitch = std::numeric_limits<double>::quiet_NaN();
} else { } else {
this->pitch = pitch * (180.0 / M_PI);
float pitchdeg = pitch * (180.0 / M_PI);
if (fabsf(pitch - pitchdeg) > 2.5f) {
_valuesChanged = true;
}
this->pitch = pitchdeg;
} }
if (isinf(yaw)) { if (isinf(yaw)) {
this->heading = std::numeric_limits<double>::quiet_NaN(); this->heading = std::numeric_limits<double>::quiet_NaN();
} else { } else {
yaw = yaw * (180.0 / M_PI); yaw = yaw * (180.0 / M_PI);
if (yaw<0) yaw+=360; if (yaw<0) yaw+=360;
if (fabsf(heading - yaw) > 10.0f) {
_valuesChanged = true;
}
this->heading = yaw; this->heading = yaw;
} }
...@@ -314,6 +347,14 @@ void PrimaryFlightDisplay::updateSpeed(UASInterface* uas, double _groundSpeed, d ...@@ -314,6 +347,14 @@ void PrimaryFlightDisplay::updateSpeed(UASInterface* uas, double _groundSpeed, d
Q_UNUSED(uas); Q_UNUSED(uas);
Q_UNUSED(timestamp); Q_UNUSED(timestamp);
if (fabsf(groundSpeed - _groundSpeed) > 0.5f) {
_valuesChanged = true;
}
if (fabsf(airSpeed - _airSpeed) > 1.0f) {
_valuesChanged = true;
}
groundSpeed = _groundSpeed; groundSpeed = _groundSpeed;
airSpeed = _airSpeed; airSpeed = _airSpeed;
} }
...@@ -321,6 +362,19 @@ void PrimaryFlightDisplay::updateSpeed(UASInterface* uas, double _groundSpeed, d ...@@ -321,6 +362,19 @@ void PrimaryFlightDisplay::updateSpeed(UASInterface* uas, double _groundSpeed, d
void PrimaryFlightDisplay::updateAltitude(UASInterface* uas, double _altitudeAMSL, double _altitudeRelative, double _climbRate, quint64 timestamp) { void PrimaryFlightDisplay::updateAltitude(UASInterface* uas, double _altitudeAMSL, double _altitudeRelative, double _climbRate, quint64 timestamp) {
Q_UNUSED(uas); Q_UNUSED(uas);
Q_UNUSED(timestamp); Q_UNUSED(timestamp);
if (fabsf(altitudeAMSL - _altitudeAMSL) > 0.5f) {
_valuesChanged = true;
}
if (fabsf(altitudeRelative - _altitudeRelative) > 0.5f) {
_valuesChanged = true;
}
if (fabsf(climbRate - _climbRate) > 0.5f) {
_valuesChanged = true;
}
altitudeAMSL = _altitudeAMSL; altitudeAMSL = _altitudeAMSL;
altitudeRelative = _altitudeRelative; altitudeRelative = _altitudeRelative;
climbRate = _climbRate; climbRate = _climbRate;
......
...@@ -27,7 +27,13 @@ public slots: ...@@ -27,7 +27,13 @@ public slots:
void forgetUAS(UASInterface* uas); void forgetUAS(UASInterface* uas);
void setActiveUAS(UASInterface* uas); void setActiveUAS(UASInterface* uas);
void checkUpdate();
protected: protected:
bool _valuesChanged;
quint64 _valuesLastPainted;
enum Layout { enum Layout {
COMPASS_INTEGRATED, COMPASS_INTEGRATED,
COMPASS_SEPARATED // For a very high container. Feature panels are at bottom. COMPASS_SEPARATED // For a very high container. Feature panels are at bottom.
......
...@@ -25,8 +25,9 @@ QGCHilXPlaneConfiguration::QGCHilXPlaneConfiguration(QGCHilLink* link, QWidget * ...@@ -25,8 +25,9 @@ QGCHilXPlaneConfiguration::QGCHilXPlaneConfiguration(QGCHilLink* link, QWidget *
{ {
// connect(ui->randomAttitudeButton, SIGNAL(clicked()), link, SLOT(setRandomAttitude())); // connect(ui->randomAttitudeButton, SIGNAL(clicked()), link, SLOT(setRandomAttitude()));
// connect(ui->randomPositionButton, SIGNAL(clicked()), link, SLOT(setRandomPosition())); // connect(ui->randomPositionButton, SIGNAL(clicked()), link, SLOT(setRandomPosition()));
connect(ui->airframeComboBox, SIGNAL(activated(QString)), link, SLOT(selectAirframe(QString)));
ui->airframeComboBox->setCurrentIndex(link->getAirFrameIndex()); ui->airframeComboBox->setCurrentIndex(link->getAirFrameIndex());
connect(ui->airframeComboBox, SIGNAL(activated(QString)), link, SLOT(selectAirframe(QString)));
// XXX not implemented yet // XXX not implemented yet
ui->airframeComboBox->hide(); ui->airframeComboBox->hide();
ui->sensorHilCheckBox->setChecked(xplane->sensorHilEnabled()); ui->sensorHilCheckBox->setChecked(xplane->sensorHilEnabled());
......
...@@ -575,6 +575,7 @@ void QGCMAVLinkLogPlayer::logLoop() ...@@ -575,6 +575,7 @@ void QGCMAVLinkLogPlayer::logLoop()
// have at least 3ms until the next one. // have at least 3ms until the next one.
int nextExecutionTime = 0; int nextExecutionTime = 0;
mavlink_message_t msg; mavlink_message_t msg;
msg.len = 0; // FIXME: Hack, remove once Issue #647 is fixed
while (nextExecutionTime < 3) { while (nextExecutionTime < 3) {
// Now we're sitting at the start of a MAVLink message, so read it all into a byte array for feeding to our parser. // Now we're sitting at the start of a MAVLink message, so read it all into a byte array for feeding to our parser.
......
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