Commit c5e1a67a authored by lm's avatar lm

Merged, improved UI when MAVs time out

parents 319623e5 3989ad94
...@@ -11,7 +11,7 @@ QT += network \ ...@@ -11,7 +11,7 @@ QT += network \
TEMPLATE = app TEMPLATE = app
TARGET = tst_uasunittest TARGET = qgcunittest
BASEDIR = $$IN_PWD BASEDIR = $$IN_PWD
TESTDIR = $$BASEDIR/qgcunittest TESTDIR = $$BASEDIR/qgcunittest
...@@ -97,8 +97,7 @@ INCLUDEPATH += . \ ...@@ -97,8 +97,7 @@ INCLUDEPATH += . \
$$BASEDIR/src/ui/ \ $$BASEDIR/src/ui/ \
SOURCES += $$TESTDIR/tst_uasunittest.cc \ SOURCES += src/uas/UAS.cc \
src/uas/UAS.cc \
src/comm/MAVLinkProtocol.cc \ src/comm/MAVLinkProtocol.cc \
src/uas/UASWaypointManager.cc \ src/uas/UASWaypointManager.cc \
src/Waypoint.cc \ src/Waypoint.cc \
...@@ -111,6 +110,10 @@ SOURCES += $$TESTDIR/tst_uasunittest.cc \ ...@@ -111,6 +110,10 @@ SOURCES += $$TESTDIR/tst_uasunittest.cc \
src/comm/LinkManager.cc \ src/comm/LinkManager.cc \
src/QGC.cc \ src/QGC.cc \
src/comm/SerialLink.cc \ src/comm/SerialLink.cc \
$$TESTDIR/SlugsMavUnitTest.cc \
$$TESTDIR/testSuite.cc \
$$TESTDIR/UASUnitTest.cc
HEADERS += src/uas/UASInterface.h \ HEADERS += src/uas/UASInterface.h \
src/uas/UAS.h \ src/uas/UAS.h \
...@@ -129,6 +132,9 @@ HEADERS += src/uas/UASInterface.h \ ...@@ -129,6 +132,9 @@ HEADERS += src/uas/UASInterface.h \
src/QGC.h \ src/QGC.h \
src/comm/SerialLinkInterface.h \ src/comm/SerialLinkInterface.h \
src/comm/SerialLink.h \ src/comm/SerialLink.h \
$$TESTDIR//SlugsMavUnitTest.h \
$$TESTDIR/AutoTest.h \
$$TESTDIR/UASUnitTest.h
......
/**
* @author Rob Caldecott
* @note This was obtained from http://qtcreator.blogspot.com/2010/04/sample-multiple-unit-test-project.html
*
*/
#ifndef AUTOTEST_H
#define AUTOTEST_H
#include <QTest>
#include <QList>
#include <QString>
#include <QSharedPointer>
namespace AutoTest
{
typedef QList<QObject*> TestList;
inline TestList& testList()
{
static TestList list;
return list;
}
inline bool findObject(QObject* object)
{
TestList& list = testList();
if (list.contains(object))
{
return true;
}
foreach (QObject* test, list)
{
if (test->objectName() == object->objectName())
{
return true;
}
}
return false;
}
inline void addTest(QObject* object)
{
TestList& list = testList();
if (!findObject(object))
{
list.append(object);
}
}
inline int run(int argc, char *argv[])
{
int ret = 0;
foreach (QObject* test, testList())
{
ret += QTest::qExec(test, argc, argv);
}
return ret;
}
}
template <class T>
class Test
{
public:
QSharedPointer<T> child;
Test(const QString& name) : child(new T)
{
child->setObjectName(name);
AutoTest::addTest(child.data());
}
};
#define DECLARE_TEST(className) static Test<className> t(#className);
#define TEST_MAIN \
int main(int argc, char *argv[]) \
{ \
return AutoTest::run(argc, argv); \
}
#endif // AUTOTEST_H
#include "SlugsMavUnitTest.h"
SlugsMavUnitTest::SlugsMavUnitTest()
{
}
void SlugsMavUnitTest::initTestCase()
{
}
void SlugsMavUnitTest::cleanupTestCase()
{
}
void SlugsMavUnitTest::first_test()
{
QCOMPARE(1,2);
}
#ifndef SLUGSMAVUNITTEST_H
#define SLUGSMAVUNITTEST_H
#include <QObject>
#include <QtCore/QString>
#include <QtTest/QtTest>
#include "UAS.h"
#include "MAVLinkProtocol.h"
#include "UASInterface.h"
#include "AutoTest.h"
class SlugsMavUnitTest : public QObject
{
Q_OBJECT
public:
SlugsMavUnitTest();
signals:
private slots:
void initTestCase();
void cleanupTestCase();
void first_test();
};
DECLARE_TEST(SlugsMavUnitTest)
#endif // SLUGSMAVUNITTEST_H
#include "UASUnitTest.h"
UASUnitTest::UASUnitTest()
{
}
void UASUnitTest::initTestCase()
{
mav= new MAVLinkProtocol();
uas=new UAS(mav,UASID);
}
void UASUnitTest::cleanupTestCase()
{
delete uas;
delete mav;
}
void UASUnitTest::getUASID_test()
{
// Test a default ID of zero is assigned
UAS* uas2 = new UAS(mav);
QCOMPARE(uas2->getUASID(), 0);
delete uas2;
// Test that the chosen ID was assigned at construction
QCOMPARE(uas->getUASID(), UASID);
// Make sure that no other ID was sert
QEXPECT_FAIL("", "When you set an ID it does not use the default ID of 0", Continue);
QCOMPARE(uas->getUASID(), 0);
}
void UASUnitTest::getUASName_test()
{
// Test that the name is build as MAV + ID
QCOMPARE(uas->getUASName(), "MAV 0" + QString::number(UASID));
}
void UASUnitTest::getUpTime_test()
{
UAS* uas2 = new UAS(mav);
// Test that the uptime starts at zero to a
// precision of seconds
QCOMPARE(floor(uas2->getUptime()/1000.0), 0.0);
// Sleep for three seconds
QTest::qSleep(3000);
// Test that the up time is computed correctly to a
// precision of seconds
QCOMPARE(floor(uas2->getUptime()/1000.0), 3.0);
delete uas2;
}
void UASUnitTest::getCommunicationStatus_test()
{
// Verify that upon construction the Comm status is disconnected
QCOMPARE(uas->getCommunicationStatus(), static_cast<int>(UASInterface::COMM_DISCONNECTED));
}
void UASUnitTest::filterVoltage_test()
{
float verificar=uas->filterVoltage(0.4f);
// Verify that upon construction the Comm status is disconnected
QCOMPARE(verificar, 8.52f);
}
void UASUnitTest:: getAutopilotType_test()
{
int verificar=uas->getAutopilotType();
// Verify that upon construction the autopilot is set to -1
QCOMPARE(verificar, -1);
}
void UASUnitTest::setAutopilotType_test()
{
uas->setAutopilotType(2);
// Verify that the autopilot is set
QCOMPARE(uas->getAutopilotType(), 2);
}
void UASUnitTest::getStatusForCode_test()
{
QString state, desc;
state = "";
desc = "";
uas->getStatusForCode(MAV_STATE_UNINIT, state, desc);
QVERIFY(state == "UNINIT");
uas->getStatusForCode(MAV_STATE_UNINIT, state, desc);
QVERIFY(state == "UNINIT");
uas->getStatusForCode(MAV_STATE_BOOT, state, desc);
QVERIFY(state == "BOOT");
uas->getStatusForCode(MAV_STATE_CALIBRATING, state, desc);
QVERIFY(state == "CALIBRATING");
uas->getStatusForCode(MAV_STATE_ACTIVE, state, desc);
QVERIFY(state == "ACTIVE");
uas->getStatusForCode(MAV_STATE_STANDBY, state, desc);
QVERIFY(state == "STANDBY");
uas->getStatusForCode(MAV_STATE_CRITICAL, state, desc);
QVERIFY(state == "CRITICAL");
uas->getStatusForCode(MAV_STATE_EMERGENCY, state, desc);
QVERIFY(state == "EMERGENCY");
uas->getStatusForCode(MAV_STATE_POWEROFF, state, desc);
QVERIFY(state == "SHUTDOWN");
uas->getStatusForCode(5325, state, desc);
QVERIFY(state == "UNKNOWN");
}
void UASUnitTest::getLocalX_test()
{
QCOMPARE(uas->getLocalX(), 0.0);
}
void UASUnitTest::getLocalY_test()
{
QCOMPARE(uas->getLocalY(), 0.0);
}
void UASUnitTest::getLocalZ_test()
{
QCOMPARE(uas->getLocalZ(), 0.0);
}
void UASUnitTest::getLatitude_test()
{ QCOMPARE(uas->getLatitude(), 0.0);
}
void UASUnitTest::getLongitude_test()
{
QCOMPARE(uas->getLongitude(), 0.0);
}
void UASUnitTest::getAltitude_test()
{
QCOMPARE(uas->getAltitude(), 0.0);
}
void UASUnitTest::getRoll_test()
{
QCOMPARE(uas->getRoll(), 0.0);
}
void UASUnitTest::getPitch_test()
{
QCOMPARE(uas->getPitch(), 0.0);
}
void UASUnitTest::getYaw_test()
{
QCOMPARE(uas->getYaw(), 0.0);
}
#ifndef UASUNITTEST_H
#define UASUNITTEST_H
#include <QObject>
#include <QtCore/QString>
#include <QtTest/QtTest>
#include "UAS.h"
#include "MAVLinkProtocol.h"
#include "UASInterface.h"
#include "AutoTest.h"
class UASUnitTest : public QObject
{
Q_OBJECT
public:
#define UASID 50
MAVLinkProtocol* mav;
UAS* uas;
UASUnitTest();
signals:
private slots:
void initTestCase();
void cleanupTestCase();
void getUASID_test();
void getUASName_test();
void getUpTime_test();
void getCommunicationStatus_test();
void filterVoltage_test();
void getAutopilotType_test();
void setAutopilotType_test();
void getStatusForCode_test();
void getLocalX_test();
void getLocalY_test();
void getLocalZ_test();
void getLatitude_test();
void getLongitude_test();
void getAltitude_test();
void getRoll_test();
void getPitch_test();
void getYaw_test();
protected:
UAS *prueba;
};
DECLARE_TEST(UASUnitTest)
#endif // UASUNITTEST_H
/**
* @author Rob Caldecott
* @note This was obtained from http://qtcreator.blogspot.com/2010/04/sample-multiple-unit-test-project.html
*
*/
#include "AutoTest.h"
#include <QDebug>
#if 1
// This is all you need to run all the tests
TEST_MAIN
#else
// Or supply your own main function
int main(int argc, char *argv[])
{
int failures = AutoTest::run(argc, argv);
if (failures == 0)
{
qDebug() << "ALL TESTS PASSED";
}
else
{
qDebug() << failures << " TESTS FAILED!";
}
return failures;
}
#endif
...@@ -41,7 +41,7 @@ This file is part of the PIXHAWK project ...@@ -41,7 +41,7 @@ This file is part of the PIXHAWK project
namespace MG namespace MG
{ {
const static int MAX_FLIGHT_TIME = 60 * 60 * 24 * 365 * 2; const static int MAX_FLIGHT_TIME = 60 * 60 * 24 * 21;
class VERSION class VERSION
{ {
......
...@@ -20,7 +20,7 @@ namespace QGC ...@@ -20,7 +20,7 @@ namespace QGC
quint64 groundTimeUsecs(); quint64 groundTimeUsecs();
int applicationVersion(); int applicationVersion();
const static int MAX_FLIGHT_TIME = 60 * 60 * 24 * 21;
class SLEEP : public QThread class SLEEP : public QThread
{ {
......
...@@ -46,7 +46,6 @@ public slots: ...@@ -46,7 +46,6 @@ public slots:
mavlink_pwm_commands_t* getPwmCommands(); mavlink_pwm_commands_t* getPwmCommands();
#endif #endif
signals: signals:
void slugsRawImu(int uasId, const mavlink_raw_imu_t& rawData); void slugsRawImu(int uasId, const mavlink_raw_imu_t& rawData);
......
...@@ -84,8 +84,8 @@ paramsOnceRequested(false) ...@@ -84,8 +84,8 @@ paramsOnceRequested(false)
{ {
color = UASInterface::getNextColor(); color = UASInterface::getNextColor();
setBattery(LIPOLY, 3); setBattery(LIPOLY, 3);
statusTimeout->setInterval(500);
connect(statusTimeout, SIGNAL(timeout()), this, SLOT(updateState())); connect(statusTimeout, SIGNAL(timeout()), this, SLOT(updateState()));
statusTimeout->start(500);
} }
UAS::~UAS() UAS::~UAS()
...@@ -101,6 +101,14 @@ int UAS::getUASID() const ...@@ -101,6 +101,14 @@ int UAS::getUASID() const
void UAS::updateState() void UAS::updateState()
{ {
// Check if heartbeat timed out
quint64 heartbeatInterval = QGC::groundTimeUsecs() - lastHeartbeat;
if (heartbeatInterval > timeoutIntervalHeartbeat)
{
emit heartbeatTimeout(heartbeatInterval);
emit heartbeatTimeout();
}
// Position lock is set by the MAVLink message handler // Position lock is set by the MAVLink message handler
// if no position lock is available, indicate an error // if no position lock is available, indicate an error
if (positionLock) if (positionLock)
...@@ -144,6 +152,7 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message) ...@@ -144,6 +152,7 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
switch (message.msgid) switch (message.msgid)
{ {
case MAVLINK_MSG_ID_HEARTBEAT: case MAVLINK_MSG_ID_HEARTBEAT:
lastHeartbeat = QGC::groundTimeUsecs();
emit heartbeat(this); emit heartbeat(this);
// Set new type if it has changed // Set new type if it has changed
if (this->type != mavlink_msg_heartbeat_get_type(&message)) if (this->type != mavlink_msg_heartbeat_get_type(&message))
...@@ -1317,6 +1326,12 @@ void UAS::setParameter(const int component, const QString& id, const float value ...@@ -1317,6 +1326,12 @@ void UAS::setParameter(const int component, const QString& id, const float value
} }
} }
void UAS::setUASName(const QString& name)
{
this->name = name;
emit nameChanged(name);
}
/** /**
* Sets an action * Sets an action
* *
......
...@@ -152,6 +152,7 @@ protected: //COMMENTS FOR TEST UNIT ...@@ -152,6 +152,7 @@ protected: //COMMENTS FOR TEST UNIT
double roll; double roll;
double pitch; double pitch;
double yaw; double yaw;
quint64 lastHeartbeat; ///< Time of the last heartbeat message
QTimer* statusTimeout; ///< Timer for various status timeouts QTimer* statusTimeout; ///< Timer for various status timeouts
QMap<int, QMap<QString, float>* > parameters; ///< All parameters QMap<int, QMap<QString, float>* > parameters; ///< All parameters
bool paramsOnceRequested; ///< If the parameter list has been read at least once bool paramsOnceRequested; ///< If the parameter list has been read at least once
...@@ -174,7 +175,10 @@ public: ...@@ -174,7 +175,10 @@ public:
void setAutopilotType(int apType) { autopilot = apType;} void setAutopilotType(int apType) { autopilot = apType;}
public slots: public slots:
/** @brief Sets an action **/
/** @brief Set a new name **/
void setUASName(const QString& name);
/** @brief Executes an action **/
void setAction(MAV_ACTION action); void setAction(MAV_ACTION action);
/** @brief Launches the system **/ /** @brief Launches the system **/
......
...@@ -92,7 +92,8 @@ public: ...@@ -92,7 +92,8 @@ public:
COMM_CONNECTED = 2, COMM_CONNECTED = 2,
/** The connection is closed **/ /** The connection is closed **/
COMM_DISCONNECTING = 3, COMM_DISCONNECTING = 3,
COMM_FAIL = 4, ///< Communication link failed COMM_FAIL = 4,
COMM_TIMEDOUT = 5///< Communication link failed
}; };
...@@ -162,6 +163,8 @@ public: ...@@ -162,6 +163,8 @@ public:
public slots: public slots:
/** @brief Set a new name for the system */
virtual void setUASName(const QString& name) = 0;
/** @brief Sets an action **/ /** @brief Sets an action **/
virtual void setAction(MAV_ACTION action) = 0; virtual void setAction(MAV_ACTION action) = 0;
...@@ -409,9 +412,18 @@ signals: ...@@ -409,9 +412,18 @@ signals:
*/ */
void irUltraSoundLocalizationChanged(UASInterface* uas, int fix); void irUltraSoundLocalizationChanged(UASInterface* uas, int fix);
// ERROR AND STATUS SIGNALS
/** @brief Heartbeat timed out */
void heartbeatTimeout();
/** @brief Heartbeat timed out */
void heartbeatTimeout(unsigned int ms);
/** @brief Name of system changed */
void nameChanged(QString newName);
protected:
// TIMEOUT CONSTANTS
static const unsigned int timeoutIntervalHeartbeat = 2000 * 1000; ///< Heartbeat timeout is 1.5 seconds
}; };
......
...@@ -58,7 +58,7 @@ UASManager* UASManager::instance() ...@@ -58,7 +58,7 @@ UASManager* UASManager::instance()
UASManager::UASManager() : UASManager::UASManager() :
activeUAS(NULL) activeUAS(NULL)
{ {
systems = QMap<int, UASInterface*>(); systems = QList<UASInterface*>();
start(QThread::LowPriority); start(QThread::LowPriority);
} }
...@@ -90,9 +90,9 @@ void UASManager::addUAS(UASInterface* uas) ...@@ -90,9 +90,9 @@ void UASManager::addUAS(UASInterface* uas)
} }
// Only execute if there is no UAS at this index // Only execute if there is no UAS at this index
if (!systems.contains(uas->getUASID())) if (!systems.contains(uas))
{ {
systems.insert(uas->getUASID(), uas); systems.append(uas);
emit UASCreated(uas); emit UASCreated(uas);
} }
...@@ -105,7 +105,7 @@ void UASManager::addUAS(UASInterface* uas) ...@@ -105,7 +105,7 @@ void UASManager::addUAS(UASInterface* uas)
QList<UASInterface*> UASManager::getUASList() QList<UASInterface*> UASManager::getUASList()
{ {
return systems.values(); return systems;
} }
UASInterface* UASManager::getActiveUAS() UASInterface* UASManager::getActiveUAS()
...@@ -176,8 +176,18 @@ void UASManager::configureActiveUAS() ...@@ -176,8 +176,18 @@ void UASManager::configureActiveUAS()
UASInterface* UASManager::getUASForId(int id) UASInterface* UASManager::getUASForId(int id)
{ {
// Return NULL pointer if UAS does not exist UASInterface* system = NULL;
return systems.value(id, NULL);
foreach(UASInterface* sys, systems)
{
if (sys->getUASID() == id)
{
system = sys;
}
}
// Return NULL if not found
return system;
} }
void UASManager::setActiveUAS(UASInterface* uas) void UASManager::setActiveUAS(UASInterface* uas)
...@@ -195,6 +205,7 @@ void UASManager::setActiveUAS(UASInterface* uas) ...@@ -195,6 +205,7 @@ void UASManager::setActiveUAS(UASInterface* uas)
emit activeUASSet(uas); emit activeUASSet(uas);
emit activeUASSet(uas->getUASID()); emit activeUASSet(uas->getUASID());
emit activeUASSetListIndex(systems.indexOf(uas));
emit activeUASStatusChanged(uas, true); emit activeUASStatusChanged(uas, true);
emit activeUASStatusChanged(uas->getUASID(), true); emit activeUASStatusChanged(uas->getUASID(), true);
} }
......
...@@ -162,7 +162,7 @@ public slots: ...@@ -162,7 +162,7 @@ public slots:
protected: protected:
UASManager(); UASManager();
QMap<int, UASInterface*> systems; QList<UASInterface*> systems;
UASInterface* activeUAS; UASInterface* activeUAS;
QMutex activeUASMutex; QMutex activeUASMutex;
...@@ -173,6 +173,8 @@ signals: ...@@ -173,6 +173,8 @@ signals:
/** @brief The UAS currently under main operator control changed */ /** @brief The UAS currently under main operator control changed */
void activeUASSet(int systemId); void activeUASSet(int systemId);
/** @brief The UAS currently under main operator control changed */ /** @brief The UAS currently under main operator control changed */
void activeUASSetListIndex(int listIndex);
/** @brief The UAS currently under main operator control changed */
void activeUASStatusChanged(UASInterface* UAS, bool active); void activeUASStatusChanged(UASInterface* UAS, bool active);
/** @brief The UAS currently under main operator control changed */ /** @brief The UAS currently under main operator control changed */
void activeUASStatusChanged(int systemId, bool active); void activeUASStatusChanged(int systemId, bool active);
......
...@@ -436,10 +436,10 @@ void MainWindow::buildPxWidgets() ...@@ -436,10 +436,10 @@ void MainWindow::buildPxWidgets()
if (!parametersDockWidget) if (!parametersDockWidget)
{ {
parametersDockWidget = new QDockWidget(tr("Onboard Parameters"), this); parametersDockWidget = new QDockWidget(tr("Calibration and Onboard Parameters"), this);
parametersDockWidget->setWidget( new ParameterInterface(this) ); parametersDockWidget->setWidget( new ParameterInterface(this) );
parametersDockWidget->setObjectName("PARAMETER_INTERFACE_DOCKWIDGET"); parametersDockWidget->setObjectName("PARAMETER_INTERFACE_DOCKWIDGET");
addToToolsMenu (parametersDockWidget, tr("Onboard Parameters"), SLOT(showToolWidget()), MENU_PARAMETERS, Qt::RightDockWidgetArea); addToToolsMenu (parametersDockWidget, tr("Calibration and Parameters"), SLOT(showToolWidget()), MENU_PARAMETERS, Qt::RightDockWidgetArea);
} }
if (!watchdogControlDockWidget) if (!watchdogControlDockWidget)
...@@ -1099,7 +1099,7 @@ void MainWindow::showStatusMessage(const QString& status) ...@@ -1099,7 +1099,7 @@ void MainWindow::showStatusMessage(const QString& status)
void MainWindow::showCriticalMessage(const QString& title, const QString& message) void MainWindow::