Commit fe4c2dca authored by Hugo Vincent's avatar Hugo Vincent

Merge branch 'master' of pixhawk.ethz.ch:groundcontrol

Conflicts:
	mavground.pri
	src/AudioOutput.h
	src/Core.cc
parents 43b95458 03f3b211
......@@ -8,7 +8,6 @@ obj
bin/*.exe
bin/*.txt
bin/mac
mavground
*pro.user
qrc_*.cpp
*.Debug
......@@ -17,4 +16,5 @@ tmp
debug
release
opengroundcontrol.xcodeproj/**
opengroundcontrol
qgroundcontrol
File added
DEPENDPATH += src
INCLUDEPATH += src
MOC_DIR = tmp
OBJECTS_DIR = obj
# Input
HEADERS += curve.h \
......@@ -52,5 +50,3 @@ SOURCES += curve.cpp \
openaerialmapadapter.cpp \
fixedimageoverlay.cpp \
emptymapadapter.cpp
QT += network
......@@ -25,10 +25,10 @@
#
#-------------------------------------------------
QT += network opengl svg xml
QT += network opengl svg xml phonon
TEMPLATE = app
TARGET = opengroundcontrol
TARGET = qgroundcontrol
BASEDIR = .
BUILDDIR = build
......@@ -38,6 +38,7 @@ LANGUAGE = C++
#CONFIG += static release console
CONFIG += static debug_and_release console
QMAKE_CFLAGS += -j8
QMAKE_CXXFLAGS += -j8
OBJECTS_DIR = $$BUILDDIR/obj
MOC_DIR = $$BUILDDIR/moc
......@@ -46,7 +47,7 @@ UI_HEADERS_DIR = src/ui/generated
# Add external libraries
INCLUDEPATH += $$BASEDIR/lib/flite/include \
$$BASEDIR/lib/flite/lang
$$BASEDIR/lib/flite/lang
#$$BASEDIR/lib/qextserialport/include
# $$BASEDIR/lib/openjaus/libjaus/include \
......@@ -58,16 +59,17 @@ message(Qt version $$[QT_VERSION])
# MAC OS X
macx {
message(Building for Mac OS X)
message(Building for Mac OS X 64bit)
CONFIG += x86_64
CONFIG -= x86 static
CONFIG -= x86 static phonon
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.5
DESTDIR = $$BASEDIR/bin/mac
INCLUDEPATH += -framework SDL \
$$BASEDIR/MAVLink/src
$$BASEDIR/MAVLink/src
LIBS += -framework IOKit \
-framework SDL \
......@@ -75,7 +77,11 @@ macx {
-framework ApplicationServices \
-lm
DEFINES += _TTY_POSIX_
# Enable function-profiling with the OS X saturn tool
debug {
#QMAKE_CXXFLAGS += -finstrument-functions
#LIBS += -lSaturn
}
ICON = $$BASEDIR/images/icons/macx.icns
}
......@@ -84,8 +90,6 @@ macx {
linux-g++ {
message(Building for GNU/Linux)
QT += phonon
debug {
DESTDIR = $$BASEDIR
......@@ -96,8 +100,6 @@ linux-g++ {
}
INCLUDEPATH += /usr/include/SDL
DEFINES += _TTY_POSIX_
HARDWARE_PLATFORM = $$system(uname -a)
contains( HARDWARE_PLATFORM, x86_64 ) {
# 64-bit Linux
......@@ -131,8 +133,6 @@ win32 {
-lmingw32 -lSDLmain -lSDL -mwindows
INCLUDEPATH += $$BASEDIR/lib/sdl/include/SDL
DEFINES += _TTY_WIN_
debug {
DESTDIR = $$BASEDIR/bin
......@@ -144,3 +144,4 @@ win32 {
}
# Include general settings for MAVGround
include(mavground.pri)
# Include serial port library
include(src/lib/qextserialport/qextserialport.pri)
# Include QWT plotting library
include(src/lib/qwt/qwt.pri)
# Include FLITE audio synthesizer library
#include(src/lib/flite/flite.pri)
# Include QMapControl map library
include(lib/QMapControl/QMapControl.pri)
DEPENDPATH += . \
lib/QMapControl \
lib/QMapControl/src
INCLUDEPATH += . \
lib/QMapControl \
../mavlink/src \
MAVLink/src \
mavlink/src
# Input
FORMS += src/ui/MainWindow.ui \
src/ui/CommSettings.ui \
src/ui/SerialSettings.ui \
src/ui/UASControl.ui \
src/ui/UASList.ui \
src/ui/UASInfo.ui \
src/ui/LineChart.ui \
src/ui/UASView.ui \
src/ui/ParameterInterface.ui \
src/ui/WaypointList.ui \
src/ui/WaypointView.ui \
src/ui/ObjectDetectionView.ui \
src/ui/JoystickWidget.ui \
src/ui/DebugConsole.ui \
src/ui/MapWidget.ui \
src/ui/XMLCommProtocolWidget.ui \
src/ui/HDDisplay.ui \
src/ui/MAVLinkSettingsWidget.ui \
src/ui/AudioOutputWidget.ui
INCLUDEPATH += src \
src/ui \
src/ui/linechart \
src/ui/uas \
src/ui/map \
src/uas \
src/comm \
include/ui \
src/input \
src/lib/qmapcontrol \
src/ui/mavlink
HEADERS += src/MG.h \
src/Core.h \
src/uas/UASInterface.h \
src/uas/UAS.h \
src/uas/UASManager.h \
src/comm/LinkManager.h \
src/comm/LinkInterface.h \
src/comm/SerialLinkInterface.h \
src/comm/SerialLink.h \
src/comm/SerialSimulationLink.h \
src/comm/ProtocolInterface.h \
src/comm/MAVLinkProtocol.h \
src/comm/AS4Protocol.h \
src/ui/CommConfigurationWindow.h \
src/ui/SerialConfigurationWindow.h \
src/ui/MainWindow.h \
src/ui/uas/UASControlWidget.h \
src/ui/uas/UASListWidget.h \
src/ui/uas/UASInfoWidget.h \
src/ui/HUD.h \
src/ui/linechart/LinechartWidget.h \
src/ui/linechart/LinechartContainer.h \
src/ui/linechart/LinechartPlot.h \
src/ui/linechart/Scrollbar.h \
src/ui/linechart/ScrollZoomer.h \
src/configuration.h \
src/ui/uas/UASView.h \
src/ui/CameraView.h \
src/comm/MAVLinkSimulationLink.h \
src/comm/UDPLink.h \
src/ui/ParameterInterface.h \
src/ui/WaypointList.h \
src/Waypoint.h \
src/ui/WaypointView.h \
src/ui/ObjectDetectionView.h \
src/input/JoystickInput.h \
src/ui/JoystickWidget.h \
src/ui/PFD.h \
src/ui/GaugePanel.h \
src/ui/DebugConsole.h \
src/ui/MapWidget.h \
src/ui/XMLCommProtocolWidget.h \
src/ui/mavlink/DomItem.h \
src/ui/mavlink/DomModel.h \
src/comm/MAVLinkXMLParser.h \
src/ui/HDDisplay.h \
src/ui/MAVLinkSettingsWidget.h \
src/ui/AudioOutputWidget.h \
src/AudioOutput.h \
src/LogCompressor.h
SOURCES += src/main.cc \
src/Core.cc \
src/uas/UASManager.cc \
src/uas/UAS.cc \
src/comm/LinkManager.cc \
src/comm/SerialLink.cc \
src/comm/SerialSimulationLink.cc \
src/comm/MAVLinkProtocol.cc \
src/comm/AS4Protocol.cc \
src/ui/CommConfigurationWindow.cc \
src/ui/SerialConfigurationWindow.cc \
src/ui/MainWindow.cc \
src/ui/uas/UASControlWidget.cc \
src/ui/uas/UASListWidget.cc \
src/ui/uas/UASInfoWidget.cc \
src/ui/HUD.cc \
src/ui/linechart/LinechartWidget.cc \
src/ui/linechart/LinechartContainer.cc \
src/ui/linechart/LinechartPlot.cc \
src/ui/linechart/Scrollbar.cc \
src/ui/linechart/ScrollZoomer.cc \
src/ui/uas/UASView.cc \
src/ui/CameraView.cc \
src/comm/MAVLinkSimulationLink.cc \
src/comm/UDPLink.cc \
src/ui/ParameterInterface.cc \
src/ui/WaypointList.cc \
src/Waypoint.cc \
src/ui/WaypointView.cc \
src/ui/ObjectDetectionView.cc \
src/input/JoystickInput.cc \
src/ui/JoystickWidget.cc \
src/ui/PFD.cc \
src/ui/GaugePanel.cc \
src/ui/DebugConsole.cc \
src/ui/MapWidget.cc \
src/ui/XMLCommProtocolWidget.cc \
src/ui/mavlink/DomItem.cc \
src/ui/mavlink/DomModel.cc \
src/comm/MAVLinkXMLParser.cc \
src/ui/HDDisplay.cc \
src/ui/MAVLinkSettingsWidget.cc \
src/ui/AudioOutputWidget.cc \
src/AudioOutput.cc \
src/LogCompressor.cc
RESOURCES = mavground.qrc
# Include general settings for MAVGround
include(mavground.pri)
# Include serial port library
include(src/lib/qextserialport/qextserialport.pri)
# Include QWT plotting library
include(src/lib/qwt/qwt.pri)
# Include FLITE audio synthesizer library
#include(src/lib/flite/flite.pri)
# Include QMapControl map library
include(src/lib/qmapcontrol/qmapcontrol.pri)
#include(lib/QMapControl/QMapControl.pri)
DEPENDPATH += . \
lib/QMapControl \
lib/QMapControl/src
INCLUDEPATH += . \
lib/QMapControl \
../mavlink/src \
MAVLink/src \
mavlink/src
# Input
FORMS += src/ui/MainWindow.ui \
src/ui/CommSettings.ui \
src/ui/SerialSettings.ui \
src/ui/UASControl.ui \
src/ui/UASList.ui \
src/ui/UASInfo.ui \
src/ui/LineChart.ui \
src/ui/UASView.ui \
src/ui/ParameterInterface.ui \
src/ui/WaypointList.ui \
src/ui/WaypointView.ui \
src/ui/ObjectDetectionView.ui \
src/ui/JoystickWidget.ui \
src/ui/DebugConsole.ui \
src/ui/MapWidget.ui \
src/ui/XMLCommProtocolWidget.ui \
src/ui/HDDisplay.ui \
src/ui/MAVLinkSettingsWidget.ui \
src/ui/AudioOutputWidget.ui
INCLUDEPATH += src \
src/ui \
src/ui/linechart \
src/ui/uas \
src/ui/map \
src/uas \
src/comm \
include/ui \
src/input \
src/lib/qmapcontrol \
src/ui/mavlink
HEADERS += src/MG.h \
src/Core.h \
src/uas/UASInterface.h \
src/uas/UAS.h \
src/uas/UASManager.h \
src/comm/LinkManager.h \
src/comm/LinkInterface.h \
src/comm/SerialLinkInterface.h \
src/comm/SerialLink.h \
src/comm/SerialSimulationLink.h \
src/comm/ProtocolInterface.h \
src/comm/MAVLinkProtocol.h \
src/comm/AS4Protocol.h \
src/ui/CommConfigurationWindow.h \
src/ui/SerialConfigurationWindow.h \
src/ui/MainWindow.h \
src/ui/uas/UASControlWidget.h \
src/ui/uas/UASListWidget.h \
src/ui/uas/UASInfoWidget.h \
src/ui/HUD.h \
src/ui/linechart/LinechartWidget.h \
src/ui/linechart/LinechartContainer.h \
src/ui/linechart/LinechartPlot.h \
src/ui/linechart/Scrollbar.h \
src/ui/linechart/ScrollZoomer.h \
src/configuration.h \
src/ui/uas/UASView.h \
src/ui/CameraView.h \
src/comm/MAVLinkSimulationLink.h \
src/comm/UDPLink.h \
src/ui/ParameterInterface.h \
src/ui/WaypointList.h \
src/Waypoint.h \
src/ui/WaypointView.h \
src/ui/ObjectDetectionView.h \
src/input/JoystickInput.h \
src/ui/JoystickWidget.h \
src/ui/PFD.h \
src/ui/GaugePanel.h \
src/ui/DebugConsole.h \
src/ui/MapWidget.h \
src/ui/XMLCommProtocolWidget.h \
src/ui/mavlink/DomItem.h \
src/ui/mavlink/DomModel.h \
src/comm/MAVLinkXMLParser.h \
src/ui/HDDisplay.h \
src/ui/MAVLinkSettingsWidget.h \
src/ui/AudioOutputWidget.h \
src/GAudioOutput.h \
src/LogCompressor.h
SOURCES += src/main.cc \
src/Core.cc \
src/uas/UASManager.cc \
src/uas/UAS.cc \
src/comm/LinkManager.cc \
src/comm/SerialLink.cc \
src/comm/SerialSimulationLink.cc \
src/comm/MAVLinkProtocol.cc \
src/comm/AS4Protocol.cc \
src/ui/CommConfigurationWindow.cc \
src/ui/SerialConfigurationWindow.cc \
src/ui/MainWindow.cc \
src/ui/uas/UASControlWidget.cc \
src/ui/uas/UASListWidget.cc \
src/ui/uas/UASInfoWidget.cc \
src/ui/HUD.cc \
src/ui/linechart/LinechartWidget.cc \
src/ui/linechart/LinechartContainer.cc \
src/ui/linechart/LinechartPlot.cc \
src/ui/linechart/Scrollbar.cc \
src/ui/linechart/ScrollZoomer.cc \
src/ui/uas/UASView.cc \
src/ui/CameraView.cc \
src/comm/MAVLinkSimulationLink.cc \
src/comm/UDPLink.cc \
src/ui/ParameterInterface.cc \
src/ui/WaypointList.cc \
src/Waypoint.cc \
src/ui/WaypointView.cc \
src/ui/ObjectDetectionView.cc \
src/input/JoystickInput.cc \
src/ui/JoystickWidget.cc \
src/ui/PFD.cc \
src/ui/GaugePanel.cc \
src/ui/DebugConsole.cc \
src/ui/MapWidget.cc \
src/ui/XMLCommProtocolWidget.cc \
src/ui/mavlink/DomItem.cc \
src/ui/mavlink/DomModel.cc \
src/comm/MAVLinkXMLParser.cc \
src/ui/HDDisplay.cc \
src/ui/MAVLinkSettingsWidget.cc \
src/ui/AudioOutputWidget.cc \
src/GAudioOutput.cc \
src/LogCompressor.cc
RESOURCES = mavground.qrc
<RCC>
<qresource prefix="/">
<qresource prefix="/" >
<file>images/control/launch.svg</file>
<file>images/status/dialog-error.svg</file>
<file>images/status/dialog-warning.svg</file>
......@@ -76,8 +76,10 @@
<file>images/status/audio-volume-low.svg</file>
<file>images/status/audio-volume-high.svg</file>
<file>images/style-mission.css</file>
<file>images/splash.png</file>
<file>audio/alert.wav</file>
</qresource>
<qresource prefix="/general">
<file alias="vera.ttf">images/Vera.ttf</file>
<qresource prefix="/general" >
<file alias="vera.ttf" >images/Vera.ttf</file>
</qresource>
</RCC>
#ifndef AUDIOOUTPUT_H
#define AUDIOOUTPUT_H
#include <QObject>
#include <QStringList>
/* Foward declarations of speech/voice structure */
#ifdef Q_OS_MAC
struct SpeechChannelRecord;
typedef SpeechChannelRecord *SpeechChannel;
#else
struct cst_voice;
#endif
class AudioOutput : public QObject
{
Q_OBJECT
public:
AudioOutput(QString voice="", QObject* parent=NULL);
/** @brief List available voices */
QStringList listVoices(void);
public slots:
/** @brief Say this text if current output priority matches */
bool say(QString text, int severity);
/** @brief Play alert sound */
bool alert(QString text);
/** @brief Start emergency sound */
bool startEmergency();
/** @brief Stop emergency sound */
bool stopEmergency();
/** @brief Select female voice */
void selectFemaleVoice();
/** @brief Select male voice */
void selectMaleVoice();
/** @brief Select neutral voice */
void selectNeutralVoice();
protected:
#ifdef Q_OS_MAC
SpeechChannel *voice;
#else
cst_voice *voice;
#endif
int voiceIndex;
};
#endif // AUDIOOUTPUT_H
......@@ -23,7 +23,7 @@ This file is part of the PIXHAWK project
/**
* @file
* @brief Main class
* @brief Implementation of main class
*
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
......@@ -43,7 +43,7 @@ This file is part of the PIXHAWK project
#include <Core.h>
#include <MG.h>
#include <MainWindow.h>
#include "AudioOutput.h"
#include "GAudioOutput.h"
/**
......@@ -56,7 +56,7 @@ This file is part of the PIXHAWK project
* @param argv The string array of parameters
**/
MGCore::MGCore(int &argc, char* argv[]) : QApplication(argc, argv)
Core::Core(int &argc, char* argv[]) : QApplication(argc, argv)
{
this->setApplicationName("OpenMAV Ground Control Station");
this->setApplicationVersion("v. 0.0.5");
......@@ -74,7 +74,7 @@ MGCore::MGCore(int &argc, char* argv[]) : QApplication(argc, argv)
setFont(fontDatabase.font(fontFamilyName, "Roman", 12));
// Show splash screen
QPixmap splashImage(MG::DIR::getIconDirectory() + "/groundstation-splash.png");
QPixmap splashImage(":images/splash.png");
QSplashScreen* splashScreen = new QSplashScreen(splashImage, Qt::WindowStaysOnTopHint);
splashScreen->show();
......@@ -87,8 +87,10 @@ MGCore::MGCore(int &argc, char* argv[]) : QApplication(argc, argv)
startUASManager();
// Start audio output
AudioOutput* audio = new AudioOutput();
audio->say("Ground Control Station started", 1);
//GAudioOutput::instance()->say("Ground Control Station started", 1);
//tarsus = new ViconTarsusProtocol();
//tarsus->start();
// Start the user interface
splashScreen->showMessage(tr("Starting User Interface"));
......@@ -104,7 +106,7 @@ MGCore::MGCore(int &argc, char* argv[]) : QApplication(argc, argv)
* @brief Destructor for the groundstation. It destroys all loaded instances.
*
**/
MGCore::~MGCore()
Core::~Core()
{
// Delete singletons
delete LinkManager::instance();
......@@ -117,7 +119,7 @@ MGCore::~MGCore()
* The link manager keeps track of all communication links and provides the global
* packet queue. It is the main communication hub
**/
void MGCore::startLinkManager()
void Core::startLinkManager()
{
LinkManager::instance();
}
......@@ -126,7 +128,7 @@ void MGCore::startLinkManager()
* @brief Start the Unmanned Air System Manager
*
**/
void MGCore::startUASManager()
void Core::startUASManager()
{
UASManager::instance();
}
......@@ -134,10 +136,10 @@ void MGCore::startUASManager()
/**
* @brief Start and show the user interface.
**/
void MGCore::startUI()
void Core::startUI()
{
// Start UI
mainWindow = new MGMainWindow();
mainWindow = new MainWindow();
// Make UI visible
mainWindow->show();
}
......
......@@ -30,14 +30,15 @@ This file is part of the PIXHAWK project
*/
#ifndef _MGCORE_H_
#define _MGCORE_H_
#ifndef _CORE_H_
#define _CORE_H_
#include <QApplication>
#include "MainWindow.h"
#include "UASManager.h"
#include "LinkManager.h"
/*#include "ViconTarsusProtocol.h" */
/**
* @brief The main application and management class.
......@@ -46,13 +47,13 @@ This file is part of the PIXHAWK project
* the central management unit of the groundstation application.
*
**/
class MGCore : public QApplication
class Core : public QApplication
{
Q_OBJECT
public:
MGCore(int &argc, char* argv[]);
~MGCore();
Core(int &argc, char* argv[]);
~Core();
protected:
void startLinkManager();
......@@ -67,7 +68,8 @@ protected:
void startUI();
private:
MGMainWindow* mainWindow;
MainWindow* mainWindow;
//ViconTarsusProtocol* tarsus;
};
#endif // _MGCORE_H_
#endif /* _CORE_H_ */
/*=====================================================================
PIXHAWK Micro Air Vehicle Flying Robotics Toolkit
(c) 2009, 2010 PIXHAWK PROJECT <http://pixhawk.ethz.ch>
This file is part of the PIXHAWK project
PIXHAWK is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PIXHAWK is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PIXHAWK. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Implementation of audio output
*
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#include <QApplication>
#include <QTemporaryFile>
#include "GAudioOutput.h"
#include "MG.h"
#include <QDebug>
#ifdef Q_OS_MAC
#include <ApplicationServices/ApplicationServices.h>
#endif
#ifdef Q_OS_WINDOWS
#include <windows.h>
using System;
using System.Speech.Synthesis;
#endif
#ifdef Q_OS_LINUX
extern "C" {
#include <flite.h>
#include <cmu_us_awb/voxdefs.h>
//#include <cmu_us_slt/voxdefs.h>
//cst_voice *REGISTER_VOX(const char *voxdir);
//void UNREGISTER_VOX(cst_voice *vox);
cst_voice *register_cmu_us_awb(const char *voxdir);
void unregister_cmu_us_awb(cst_voice *vox);
cst_voice *register_cmu_us_slt(const char *voxdir);
void unregister_cmu_us_slt(cst_voice *vox);
cst_voice *register_cmu_us_rms(const char *voxdir);
void unregister_cmu_us_rms(cst_voice *vox);
};
#endif
/**
* This class follows the singleton design pattern
* @see http://en.wikipedia.org/wiki/Singleton_pattern
* A call to this function thus returns the only instance of this object
* the call can occur at any place in the code, no reference to the
* GAudioOutput object has to be passed.
*/
GAudioOutput* GAudioOutput::instance()
{
static GAudioOutput* _instance = 0;
if(_instance == 0) {
_instance = new GAudioOutput();
// Set the application as parent to ensure that this object
// will be destroyed when the main application exits
_instance->setParent(qApp);
}
return _instance;
}
GAudioOutput::GAudioOutput(QObject* parent) : QObject(parent),
#ifdef Q_OS_LINUX
voice(NULL),
#endif
voiceIndex(0),
emergency(false)
{
#ifdef Q_OS_LINUX
flite_init();
#endif
m_media = new Phonon::MediaObject(this);
Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
createPath(m_media, audioOutput);
emergencyTimer = new QTimer();
connect(emergencyTimer, SIGNAL(timeout()), this, SLOT(beep()));
switch (voiceIndex)
{
case 0:
selectFemaleVoice();
break;
case 1:
selectMaleVoice();
break;
default:
selectNeutralVoice();
break;
}
}
bool GAudioOutput::say(QString text, int severity)
{
bool res = false;
if (!emergency)
{
#ifdef Q_OS_WINDOWS
SpeechSynthesizer synth = new SpeechSynthesizer();
synth.SelectVoice("Microsoft Anna");
synth.SpeakText("Hello, world!");
#endif
#ifdef Q_OS_LINUX
QTemporaryFile file;
file.setFileTemplate("XXXXXX.wav");
if (file.open())
{
cst_wave* wav = flite_text_to_wave(text.toStdString().c_str(), this->voice);
// file.fileName() returns the unique file name
cst_wave_save(wav, file.fileName().toStdString().c_str(), "riff");
m_media->setCurrentSource(Phonon::MediaSource(file.fileName().toStdString().c_str()));
qDebug() << "TYPE:" << m_media->currentSource().type();
m_media->play();
qDebug() << "Synthesized: " << text << ", tmp file:" << file.fileName().toStdString().c_str();
res = true;
}
#endif
#ifdef Q_OS_MAC
// Slashes necessary to have the right start to the sentence
// copying data prevents SpeakString from reading additional chars
text = "\\" + text;
QStdWString str = text.toStdWString();
unsigned char str2[1024] = {};
memcpy(str2, text.toAscii().data(), str.length());
SpeakString(str2);
qDebug() << "Synthesized: " << text.toAscii();
#endif
#ifdef Q_OS_WIN32
qDebug() << "Synthesized: " << text << ", NO OUTPUT SUPPORT ON WINDOWS!";
#endif
}
return res;
}
/**
* @param text This message will be played after the alert beep
*/
bool GAudioOutput::alert(QString text)
{
if (!emergency)
{
// Play alert sound
m_media->setCurrentSource(Phonon::MediaSource(QString("alert.wav").toStdString().c_str()));
qDebug() << "FILENAME:" << m_media->currentSource().fileName();
qDebug() << "TYPE:" << m_media->currentSource().type();
qDebug() << QString("alert.wav").toStdString().c_str();
m_media->play();
m_media->setCurrentSource(Phonon::MediaSource(QString("alert.wav").toStdString().c_str()));
m_media->play();
// Say alert message
return true;//say(text, 2);
}
else
{
return false;
}
}
/**
* The emergency sound will be played continously during the emergency.
* call stopEmergency() to disable it again. No speech synthesis or other
* audio output is available during the emergency.
*
* @return true if the emergency could be started, false else
*/
bool GAudioOutput::startEmergency()
{
if (!emergency)
{
emergency = true;
emergencyTimer->start(1600);
}
return true;
}
/**
* Stops the continous emergency sound. Use startEmergency() to start
* the emergency sound.
*
* @return true if the emergency could be stopped, false else
*/
bool GAudioOutput::stopEmergency()
{
if (emergency)
{
emergency = false;
emergencyTimer->stop();
}
return true;
}
void GAudioOutput::beep()
{
m_media->setCurrentSource(Phonon::MediaSource(QString("alert.wav").toStdString().c_str()));
m_media->play();
}
void GAudioOutput::selectFemaleVoice()
{
#ifdef Q_OS_LINUX
//this->voice = register_cmu_us_slt(NULL);
#endif
}
void GAudioOutput::selectMaleVoice()
{
#ifdef Q_OS_LINUX
//this->voice = register_cmu_us_rms(NULL);
#endif
}
void GAudioOutput::selectNeutralVoice()
{
#ifdef Q_OS_LINUX
//this->voice = register_cmu_us_awb(NULL);
#endif
}
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
QStringList GAudioOutput::listVoices(void)
{
QStringList l;
#ifdef Q_OS_LINUX
cst_voice *voice;
const cst_val *v;
/*
printf("Voices available: ");
for (v=flite_voice_list; v; v=val_cdr(v))
{
voice = val_voice(val_car(v));
QString s;
s.sprintf("%s",voice->name);
printf("%s",voice->name);
l.append(s);
}
printf("\n");
*/
#endif
return l;
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
/*=====================================================================
PIXHAWK Micro Air Vehicle Flying Robotics Toolkit
(c) 2009, 2010 PIXHAWK PROJECT <http://pixhawk.ethz.ch>
This file is part of the PIXHAWK project
PIXHAWK is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PIXHAWK is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PIXHAWK. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Definition of audio output
*
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#ifndef GAUDIOOUTPUT_H
#define GAUDIOOUTPUT_H
#include <QObject>
#include <QTimer>
#include <QStringList>
#ifdef Q_OS_MAC
#include <Phonon>
#endif
#ifdef Q_OS_LINUX
#include <flite.h>
#include <phonon>
#endif
#ifdef Q_OS_WIN
#include <Phonon>
#endif
/* For Snow leopard and later
#ifdef Q_OS_MAC
#include <NSSpeechSynthesizer.h>
#endif
*/
/**
* @brief Audio Output (speech synthesizer and "beep" output)
* This class follows the singleton design pattern
* @see http://en.wikipedia.org/wiki/Singleton_pattern
*/
class GAudioOutput : public QObject
{
Q_OBJECT
public:
/** @brief Get the singleton instance */
static GAudioOutput* instance();
/** @brief List available voices */
QStringList listVoices(void);
public slots:
/** @brief Say this text if current output priority matches */
bool say(QString text, int severity=1);
/** @brief Play alert sound */
bool alert(QString text);
/** @brief Start emergency sound */
bool startEmergency();
/** @brief Stop emergency sound */
bool stopEmergency();
/** @brief Select female voice */
void selectFemaleVoice();
/** @brief Select male voice */
void selectMaleVoice();
/** @brief Select neutral voice */
void selectNeutralVoice();
/** @brief Play emergency sound */
void beep();
protected:
#ifdef Q_OS_MAC
//NSSpeechSynthesizer
#endif
#ifdef Q_OS_LINUX
cst_voice* voice; ///< The flite voice object
#endif
int voiceIndex; ///< The index of the flite voice to use (awb, slt, rms)
Phonon::MediaObject* m_media; ///< The output object for audio
Phonon::AudioOutput* m_audioOutput;
bool emergency; ///< Emergency status flag
QTimer* emergencyTimer;
private:
GAudioOutput(QObject* parent=NULL);
};
#endif // AUDIOOUTPUT_H
......@@ -2,7 +2,7 @@
PIXHAWK Micro Air Vehicle Flying Robotics Toolkit
(c) 2009 PIXHAWK PROJECT <http://pixhawk.ethz.ch>
(c) 2009, 2010 PIXHAWK PROJECT <http://pixhawk.ethz.ch>
This file is part of the PIXHAWK project
......
......@@ -57,20 +57,9 @@ MAVLinkSimulationLink::MAVLinkSimulationLink(QString readFile, QString writeFile
readyBytes(0),
timeOffset(0)
{
this->id = getNextLinkId();
LinkManager::instance()->add(this);
this->rate = rate;
_isConnected = false;
if (readFile != "")
{
this->name = "Simulation: " + readFile;
}
else
{
this->name = "MAVLink simulation link";
}
// Comments on the variables can be found in the header file
simulationFile = new QFile(readFile, this);
......@@ -81,10 +70,20 @@ MAVLinkSimulationLink::MAVLinkSimulationLink(QString readFile, QString writeFile
receiveFile = new QFile(writeFile, this);
lastSent = MG::TIME::getGroundTimeNow();
if (simulationFile->exists())
{
this->name = "Simulation: " + QFileInfo(simulationFile->fileName()).fileName();
}
else
{
this->name = "MAVLink simulation link";
}
// Initialize the pseudo-random number generator
srand(QTime::currentTime().msec());
maxTimeNoise = 0;
this->id = getNextLinkId();
LinkManager::instance()->add(this);
}
MAVLinkSimulationLink::~MAVLinkSimulationLink()
......@@ -390,6 +389,32 @@ void MAVLinkSimulationLink::mainloop()
memcpy(stream+streampointer,buffer, bufferlength);
streampointer += bufferlength;
/*
// HEARTBEAT VEHICLE 2
// Pack message and get size of encoded byte string
messageSize = message_heartbeat_pack(42, componentId, &msg, MAV_FIXED_WING);
// Allocate buffer with packet data
bufferlength = message_to_send_buffer(buffer, &msg);
//add data into datastream
memcpy(stream+streampointer,buffer, bufferlength);
streampointer += bufferlength;
// STATUS VEHICLE 2
sys_status_t status2;
status2.mode = MAV_MODE_LOCKED;
status2.vbat = voltage;
status2.status = MAV_STATE_STANDBY;
// Pack message and get size of encoded byte string
messageSize = message_sys_status_encode(systemId, componentId, &msg, &status);
// Allocate buffer with packet data
bufferlength = message_to_send_buffer(buffer, &msg);
//add data into datastream
memcpy(stream+streampointer,buffer, bufferlength);
streampointer += bufferlength;
*/
//qDebug() << "BOOT" << "BUF LEN" << bufferlength << "POINTER" << streampointer;
// AUX STATUS
......
......@@ -180,9 +180,10 @@ bool MAVLinkXMLParser::generate()
QDateTime now = QDateTime::currentDateTime().toUTC();
QString dateFormat = "dddd, MMMM d yyyy, hh:mm UTC";
QString date = now.toString(dateFormat);
QString mainHeader = QString("/** @file\n *\t@brief MAVLink comm protocol.\n *\t@see http://pixhawk.ethz.ch/software/mavlink\n *\t Generated on %1\n */\n#ifndef MAVLINK_H\n#define MAVLINK_H\n\n#include \"protocol.h\"\n\n\n").arg(date); // The main header includes all messages
QString mainHeader = QString("/** @file\n *\t@brief MAVLink comm protocol.\n *\t@see http://pixhawk.ethz.ch/software/mavlink\n *\t Generated on %1\n */\n#ifndef MAVLINK_H\n#define MAVLINK_H\n\n").arg(date); // The main header includes all messages
// Mark all code as C code
mainHeader += "#ifdef __cplusplus\nextern \"C\" {\n#endif\n";
mainHeader += "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n";
mainHeader += "\n#include \"protocol.h\"\n";
QString includeLine = "#include \"%1\"\n";
QString mainHeaderName = "mavlink.h";
QString messagesDirName = "generated";
......@@ -200,6 +201,8 @@ bool MAVLinkXMLParser::generate()
mainHeader += "#ifdef __cplusplus\n}\n#endif\n";
mainHeader += "#endif";
// Newline to make compiler happy
mainHeader += "\n";
// Write main header
QFile rawHeader(outputDirName + "/" + mainHeaderName);
......
......@@ -48,9 +48,7 @@ UDPLink::UDPLink(QHostAddress host, quint16 port)
// Set unique ID and add link to the list of links
this->id = getNextLinkId();
name = tr("UDP link ") + QString::number(getId()) + tr(" (unconfigured)");
this->name = tr("UDP link ") + QString::number(getId());
LinkManager::instance()->add(this);
}
......
DEPENDPATH += src
INCLUDEPATH += src
# Input
HEADERS += curve.h \
geometry.h \
imagemanager.h \
layer.h \
layermanager.h \
linestring.h \
mapadapter.h \
mapcontrol.h \
mapnetwork.h \
point.h \
tilemapadapter.h \
wmsmapadapter.h \
circlepoint.h \
imagepoint.h \
gps_position.h \
osmmapadapter.h \
maplayer.h \
geometrylayer.h \
yahoomapadapter.h \
googlemapadapter.h \
googlesatmapadapter.h \
openaerialmapadapter.h \
fixedimageoverlay.h \
emptymapadapter.h
SOURCES += curve.cpp \
geometry.cpp \
imagemanager.cpp \
layer.cpp \
layermanager.cpp \
linestring.cpp \
mapadapter.cpp \
mapcontrol.cpp \
mapnetwork.cpp \
point.cpp \
tilemapadapter.cpp \
wmsmapadapter.cpp \
circlepoint.cpp \
imagepoint.cpp \
gps_position.cpp \
osmmapadapter.cpp \
maplayer.cpp \
geometrylayer.cpp \
yahoomapadapter.cpp \
googlemapadapter.cpp \
googlesatmapadapter.cpp \
openaerialmapadapter.cpp \
fixedimageoverlay.cpp \
emptymapadapter.cpp
......@@ -77,7 +77,7 @@ HEADERS += $$QWTSRCDIR/qwt.h \
$$QWTSRCDIR/qwt_thermo.h \
$$QWTSRCDIR/qwt_valuelist.h \
$$QWTSRCDIR/qwt_wheel.h
SOURCES += qwt_abstract_scale.cpp \
SOURCES += $$QWTSRCDIR/qwt_abstract_scale.cpp \
$$QWTSRCDIR/qwt_abstract_scale_draw.cpp \
$$QWTSRCDIR/qwt_abstract_slider.cpp \
$$QWTSRCDIR/qwt_analog_clock.cpp \
......
......@@ -48,6 +48,6 @@ This file is part of the PIXHAWK project
int main(int argc, char *argv[])
{
MGCore core(argc, argv);
Core core(argc, argv);
return core.exec();
}
......@@ -39,6 +39,7 @@ This file is part of the PIXHAWK project
#include "LinkInterface.h"
#include "UASManager.h"
#include "MG.h"
#include "GAudioOutput.h"
#include "mavlink.h"
UAS::UAS(int id=0) :
......@@ -47,19 +48,21 @@ UAS::UAS(int id=0) :
name(""),
links(new QList<LinkInterface*>()),
thrustSum(0),
thrustMax(10),
startVoltage(0),
manualRollAngle(0),
manualPitchAngle(0),
manualYawAngle(0),
manualThrust(0),
currentVoltage(0.0f),
lpVoltage(0.0f),
mode(MAV_MODE_UNINIT),
status(MAV_STATE_UNINIT),
onboardTimeOffset(0),
controlRollManual(true),
controlPitchManual(true),
controlYawManual(true),
currentVoltage(0.0f),
controlThrustManual(true),
lpVoltage(0.0f),
mode(MAV_MODE_UNINIT),
onboardTimeOffset(0)
manualRollAngle(0),
manualPitchAngle(0),
manualYawAngle(0),
manualThrust(0)
{
uasId = id;
setBattery(LIPOLY, 3);
......@@ -82,8 +85,6 @@ void UAS::setSelected()
void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
{
if (!links->contains(link))
{
addLink(link);
......@@ -94,7 +95,6 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
QString uasState;
QString stateDescription;
QString patternPath;
bool uasIsAuto;
switch (message.msgid)
{
case MAVLINK_MSG_ID_HEARTBEAT:
......@@ -107,8 +107,6 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
}
break;
case MAVLINK_MSG_ID_BOOT:
//std::cerr << "Boot detected, software v." << std::dec << message_boot_get_version(message.payload) << " time: " << MG::TIME::getGroundTimeNow() << std::endl;
//emit valueChanged(uasId, "Software version", message_boot_get_version(message.payload), MG::TIME::getGroundTimeNow());
getStatusForCode((int)MAV_STATE_BOOT, uasState, stateDescription);
emit statusChanged(this, uasState, stateDescription);
onboardTimeOffset = 0; // Reset offset measurement
......@@ -117,37 +115,56 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
{
sys_status_t state;
message_sys_status_decode(&message, &state);
getStatusForCode((int)state.status, uasState, stateDescription);
emit statusChanged(this, uasState, stateDescription);
QString mode;
QString audiostring = "System " + QString::number(this->getUASID());
QString stateAudio = "";
QString modeAudio = "";
bool statechanged = false;
bool modechanged = false;
switch (state.mode)
if (state.status != this->status)
{
case MAV_MODE_LOCKED:
mode = "MAV_MODE_LOCKED";
break;
case MAV_MODE_MANUAL:
mode = "MAV_MODE_MANUAL";
break;
case MAV_MODE_AUTO:
mode = "MAV_MODE_AUTO";
break;
case MAV_MODE_TEST1:
mode = "MAV_MODE_TEST1";
break;
case MAV_MODE_TEST2:
mode = "MAV_MODE_TEST2";
break;
case MAV_MODE_TEST3:
mode = "MAV_MODE_TEST3";
break;
default:
mode = "MAV_MODE_UNINIT";
break;
statechanged = true;
this->status = state.status;
getStatusForCode((int)state.status, uasState, stateDescription);
emit statusChanged(this, uasState, stateDescription);
stateAudio = " changed status to " + uasState;
}
emit modeChanged(this->getUASID(), mode, "");
if (static_cast<int>(this->mode) != static_cast<int>(state.mode))
{
modechanged = true;
this->mode = state.mode;
QString mode;
switch (state.mode)
{
case MAV_MODE_LOCKED:
mode = "LOCKED MODE";
break;
case MAV_MODE_MANUAL:
mode = "MANUAL MODE";
break;
case MAV_MODE_AUTO:
mode = "AUTO MODE";
break;
case MAV_MODE_TEST1:
mode = "TEST1 MODE";
break;
case MAV_MODE_TEST2:
mode = "TEST2 MODE";
break;
case MAV_MODE_TEST3:
mode = "TEST3 MODE";
break;
default:
mode = "UNINIT MODE";
break;
}
emit modeChanged(this->getUASID(), mode, "");
modeAudio = " is now in " + mode;
}
currentVoltage = state.vbat;
filterVoltage(currentVoltage);
if (startVoltage == 0) startVoltage = currentVoltage;
......@@ -155,6 +172,27 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
//qDebug() << "Voltage: " << currentVoltage << " Chargelevel: " << getChargeLevel() << " Time remaining " << timeRemaining;
emit batteryChanged(this, filterVoltage(), getChargeLevel(), timeRemaining);
emit voltageChanged(message.sysid, state.vbat/1000.0f);
// Output audio
if (modechanged && statechanged)
{
// Output both messages
audiostring += modeAudio + " and " + stateAudio;
}
else
{
// Output the one message
audiostring += modeAudio + stateAudio;
}
if (state.status == (int)MAV_STATE_CRITICAL || state.status == (int)MAV_STATE_EMERGENCY)
{
GAudioOutput::instance()->startEmergency();
}
else if (modechanged || statechanged)
{
GAudioOutput::instance()->stopEmergency();
GAudioOutput::instance()->say(audiostring);
}
}
break;
case MAVLINK_MSG_ID_RAW_IMU:
......@@ -212,40 +250,14 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
emit attitudeChanged(this, message_attitude_get_roll(&message), message_attitude_get_pitch(&message), message_attitude_get_yaw(&message), time);
}
break;
//case MAVLINK_MSG_ID_DEBUG:
// emit valueChanged(uasId, QString("debug ") + QString::number(message_debug_get_index(message.payload)), message_debug_get_value(message.payload), MG::TIME::getGroundTimeNow());
// break;
/*
case MAVLINK_MSG_ID_DEBUG:
emit valueChanged(uasId, QString("debug ") + QString::number(message_debug_get_index(message.payload)), message_debug_get_value(message.payload), MG::TIME::getGroundTimeNow());
break;
case MAVLINK_MSG_ID_MODE:
{
switch(static_cast<int>(message_mode_get_mode(message.payload)))
{
case (int)MAV_MODE_MANUAL:
{
uasIsAuto = false;
}
break;
case (int)MAV_MODE_AUTO:
{
uasIsAuto = true;
}
break;
default:
{
uasIsAuto = false;
}
break;
}
emit autoModeChanged(mode);
emit valueChanged(uasId, "auto mode", static_cast<int>(message_mode_get_mode(message.payload)), MG::TIME::getGroundTimeNow());
//qDebug() << "UAS MODE CHANGED TO AUTO, UAS MODE CHANGED TO AUTO, UAS MODE CHANGED TO AUTO, UAS MODE CHANGED TO AUTO, UAS MODE CHANGED TO AUTO, UAS MODE CHANGED TO AUTO, UAS MODE CHANGED TO AUTO:" << uasIsAuto;
}
break;
case MAVLINK_MSG_ID_EMITWAYPT:
case MAVLINK_MSG_ID_WP:
emit waypointUpdated(this->getUASID(), message_emitwaypoint_get_id(message.payload), message_emitwaypoint_get_x(message.payload), message_emitwaypoint_get_y(message.payload), message_emitwaypoint_get_z(message.payload), message_emitwaypoint_get_yaw(message.payload), (message_emitwaypoint_get_autocontinue(message.payload) == 1 ? true : false), (message_emitwaypoint_get_active(message.payload) == 1 ? true : false));
break;
case MAVLINK_MSG_ID_GOTOWAYPT:
case MAVLINK_MSG_ID_SET_POSITION:
emit valueChanged(uasId, "WP X", message_gotowaypoint_get_x(message.payload), MG::TIME::getGroundTimeNow());
emit valueChanged(uasId, "WP Y", message_gotowaypoint_get_y(message.payload), MG::TIME::getGroundTimeNow());
emit valueChanged(uasId, "WP Z", message_gotowaypoint_get_z(message.payload), MG::TIME::getGroundTimeNow());
......@@ -258,41 +270,19 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
qDebug() << "WAYPOINT REACHED";
emit waypointReached(this, message_wp_reached_get_id(message.payload));
break;
case MAVLINK_MSG_ID_DETECTION:
patternPath = QString(message_detection_get_patternpath(message.payload));
case MAVLINK_MSG_ID_OBJ_DETECTED:
//patternPath = QString(message_detection_get_patternpath(message.payload));
//qDebug() << "OBJECT DETECTED";
emit detectionReceived(uasId, patternPath, 0, 0, 0, 0, 0, 0, 0, 0, message_detection_get_confidence(message.payload), (message_detection_get_detected(message.payload) == 1 ? true : false ));
//emit detectionReceived(uasId, patternPath, 0, 0, 0, 0, 0, 0, 0, 0, message_detection_get_confidence(message.payload), (message_detection_get_detected(message.payload) == 1 ? true : false ));
break;
*/
default:
std::cerr << "Unable to decode message from system " << std::dec << static_cast<int>(message.acid) << " with message id:" << static_cast<int>(message.msgid) << std::endl;
GAudioOutput::instance()->say("COMM ERROR: UNABLE TO DECODE MESSAGE WITH ID" + QString::number(message.msgid) + "FROM SYSTEM " + QString::number(message.sysid));
std::cerr << "Unable to decode message from system " << std::dec << static_cast<int>(message.sysid) << " with message id:" << static_cast<int>(message.msgid) << std::endl;
//qDebug() << std::cerr << "Unable to decode message from system " << std::dec << static_cast<int>(message.acid) << " with message id:" << static_cast<int>(message.msgid) << std::endl;
break;
*/
}
}
// virtual void attitudeChanged(int uasId, double roll, double pitch, double yaw, quint64 usec);
// virtual void localPositionChanged(int uasId, double x, double y, double z, quint64 usec);
// virtual void globalPositionChanged(int uasId, double lon, double lat, double alt, quint64 usec);
// virtual void actuatorsChanged(int uasId, double actuator1, double actuator2, double actuator3, double actuator4, double actuator5);
// virtual void voltageChanged(int uasId, double voltage);
}
void UAS::setAutoMode(bool autoMode)
{
mavlink_message_t msg;
if (autoMode)
{
message_set_mode_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, getUASID(), (unsigned char)MAV_MODE_AUTO);
mode = MAV_MODE_AUTO;
sendMessage(msg);
}
else
{
message_set_mode_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, getUASID(), (unsigned char)MAV_MODE_MANUAL);
mode = MAV_MODE_MANUAL;
sendMessage(msg);
}
}
void UAS::setMode(int mode)
......@@ -501,10 +491,10 @@ void UAS::receiveButton(int buttonIndex)
switch (buttonIndex)
{
case 0:
setAutoMode(false);
break;
case 1:
setAutoMode(true);
break;
default:
......@@ -631,7 +621,7 @@ void UAS::shutdown()
/**
* @return The name of this system as string in human-readable form
*/
QString UAS::getUASName()
QString UAS::getUASName(void)
{
QString result;
if (name == "")
......
/*=====================================================================
PIXHAWK Micro Air Vehicle Flying Robotics Toolkit
Please see our website at <http://pixhawk.ethz.ch>
(c) 2009, 2010 PIXHAWK PROJECT <http://pixhawk.ethz.ch>
......@@ -33,7 +32,6 @@ This file is part of the PIXHAWK project
#ifndef _UAS_H_
#define _UAS_H_
#include <QDebug>
#include "UASInterface.h"
#include "MG.h"
#include <mavlink.h>
......@@ -67,7 +65,7 @@ public:
/* MANAGEMENT */
/** @brief The name of the robot */
QString getUASName();
QString getUASName(void);
/** @brief Get the unique system id */
int getUASID();
/** @brief The time interval the robot is switched on */
......@@ -83,13 +81,13 @@ public:
protected:
int type;
quint64 startTime; ///< The time the UAS was switched on
CommStatus commStatus; ///< Communication status
int uasId; ///< Unique system ID
QString name; ///< Human-friendly name of the vehicle, e.g. bravo
quint64 startTime; ///< The time the UAS was switched on
CommStatus commStatus; ///< Communication status
int uasId; ///< Unique system ID
QString name; ///< Human-friendly name of the vehicle, e.g. bravo
QList<LinkInterface*>* links; ///< List of links this UAS can be reached by
BatteryType batteryType; ///< The battery type
int cells; ///< Number of cells
BatteryType batteryType; ///< The battery type
int cells; ///< Number of cells
QList<double> actuatorValues;
QList<QString> actuatorNames;
......@@ -97,27 +95,30 @@ protected:
QList<double> motorValues;
QList<QString> motorNames;
double thrustSum; ///< Sum of forward/up thrust of all thrust actuators
double thrustSum; ///< Sum of forward/up thrust of all thrust actuators, in Newtons
double thrustMax; ///< Maximum forward/up thrust of this vehicle, in Newtons
// Battery stats
double fullVoltage; ///< Voltage of the fully charged battery (100%)
double emptyVoltage; ///< Voltage of the empty battery (0%)
double startVoltage; ///< Voltage at system start
double currentVoltage; ///< Voltage currently measured
float lpVoltage; ///< Low-pass filtered voltage
int timeRemaining; ///< Remaining time calculated based on previous and current
double manualRollAngle; ///< Roll angle set by human pilot (radians)
double manualPitchAngle; ///< Pitch angle set by human pilot (radians)
double manualYawAngle; ///< Yaw angle set by human pilot (radians)
double manualThrust; ///< Thrust set by human pilot (radians)
bool controlRollManual; ///< status flag, true if roll is controlled manually
bool controlPitchManual; ///< status flag, true if pitch is controlled manually
bool controlYawManual; ///< status flag, true if yaw is controlled manually
bool controlThrustManual;///< status flag, true if thrust is controlled manually
int mode; ///< The current mode of the MAV
double fullVoltage; ///< Voltage of the fully charged battery (100%)
double emptyVoltage; ///< Voltage of the empty battery (0%)
double startVoltage; ///< Voltage at system start
double currentVoltage; ///< Voltage currently measured
float lpVoltage; ///< Low-pass filtered voltage
int timeRemaining; ///< Remaining time calculated based on previous and current
int mode; ///< The current mode of the MAV
int status; ///< The current status of the MAV
quint64 onboardTimeOffset;
bool controlRollManual; ///< status flag, true if roll is controlled manually
bool controlPitchManual; ///< status flag, true if pitch is controlled manually
bool controlYawManual; ///< status flag, true if yaw is controlled manually
bool controlThrustManual; ///< status flag, true if thrust is controlled manually
double manualRollAngle; ///< Roll angle set by human pilot (radians)
double manualPitchAngle; ///< Pitch angle set by human pilot (radians)
double manualYawAngle; ///< Yaw angle set by human pilot (radians)
double manualThrust; ///< Thrust set by human pilot (radians)
/** @brief Set the current battery type */
void setBattery(BatteryType type, int cells);
/** @brief Estimate how much flight time is remaining */
......@@ -147,8 +148,6 @@ public slots:
/** @brief Shut the system cleanly down. Will shut down any onboard computers **/
void shutdown();
/** @brief Set the auto mode. **/
void setAutoMode(bool autoMode);
void requestWaypoints();
void clearWaypointList();
/** @brief Enable the motors */
......@@ -161,9 +160,7 @@ public slots:
/** @brief Receive a button pressed event from an input device, e.g. joystick */
void receiveButton(int buttonIndex);
/**
* @brief Add a link associated with this robot
*/
/** @brief Add a link associated with this robot */
void addLink(LinkInterface* link);
/** @brief Receive a message from one of the communication links. */
......
......@@ -110,8 +110,7 @@ public:
{
///> Color map for plots, includes 20 colors
///> Map will start from beginning when the first 20 colors are exceeded
colors.append(QColor(242,255,128));
colors.append(QColor(230,126,23));
colors.append(QColor(203,254,121));
colors.append(QColor(231,72,28));
colors.append(QColor(161,252,116));
......@@ -129,6 +128,8 @@ public:
colors.append(QColor(81,183,244));
colors.append(QColor(104,64,240));
colors.append(QColor(75,133,243));
colors.append(QColor(242,255,128));
colors.append(QColor(230,126,23));
nextColor++;
}
return colors[nextColor++];
......@@ -153,12 +154,7 @@ public slots:
virtual void halt() = 0;
/** @brief Start/continue the current robot action */
virtual void go() = 0;
/** @brief Set robot into auto mode
*
* @param autoMode true for autonomous operation, false for manual control
*/
virtual void setAutoMode(bool autoMode) = 0;
/** @brief Set the current mode of operation */
virtual void setMode(int mode) = 0;
/** Stops the robot system. If it is an MAV, the robot starts the emergency landing procedure **/
virtual void emergencySTOP() = 0;
......
......@@ -23,7 +23,7 @@ This file is part of the PIXHAWK project
/**
* @file
* @brief Central manager for all connected aerial vehicles
* @brief Implementation of central manager for all connected aerial vehicles
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
......@@ -41,8 +41,8 @@ UASManager* UASManager::instance() {
if(_instance == 0) {
_instance = new UASManager();
/* Set the application as parent to ensure that this object
* will be destroyed when the main application exits */
// Set the application as parent to ensure that this object
// will be destroyed when the main application exits
_instance->setParent(qApp);
}
return _instance;
......@@ -144,12 +144,6 @@ bool UASManager::shutdownActiveUAS()
return (activeUAS);
}
bool UASManager::setActiveUASAuto(bool autoMode)
{
if (getActiveUAS()) activeUAS->setAutoMode(autoMode);
return (activeUAS);
}
void UASManager::configureActiveUAS()
{
UASInterface* actUAS = getActiveUAS();
......@@ -165,14 +159,17 @@ UASInterface* UASManager::getUASForId(int id)
return systems.value(id, NULL);
}
void UASManager::setActiveUAS(UASInterface* UAS)
void UASManager::setActiveUAS(UASInterface* uas)
{
activeUASMutex.lock();
activeUAS = UAS;
activeUASMutex.unlock();
if (uas != NULL)
{
activeUASMutex.lock();
activeUAS = uas;
activeUASMutex.unlock();
qDebug() << __FILE__ << ":" << __LINE__ << " ACTIVE UAS SET TO: " << UAS->getUASName();
qDebug() << __FILE__ << ":" << __LINE__ << " ACTIVE UAS SET TO: " << uas->getUASName();
emit activeUASSet(UAS);
emit activeUASSet(uas);
}
}
......@@ -23,7 +23,7 @@ This file is part of the PIXHAWK project
/**
* @file
* @brief Central manager for all connected aerial vehicles
* @brief Definition of central manager for all connected aerial vehicles
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
......@@ -153,10 +153,9 @@ public slots:
*/
void configureActiveUAS();
/** @brief Shut down the onboard operating system down */
bool shutdownActiveUAS();
bool setActiveUASAuto(bool autoMode);
protected:
UASManager();
......@@ -164,9 +163,6 @@ protected:
UASInterface* activeUAS;
QMutex activeUASMutex;
private:
static UASManager* _instance;
signals:
void UASCreated(UASInterface* UAS);
void activeUASSet(UASInterface* UAS);
......
......@@ -108,10 +108,14 @@ DebugConsole::~DebugConsole()
delete m_ui;
}
/**
* Add a link to the debug console output
*/
void DebugConsole::addLink(LinkInterface* link)
{
// Add link to link list
links.insert(link->getId(), link);
m_ui->linkComboBox->insertItem(link->getId(), link->getName());
// Set new item as current
m_ui->linkComboBox->setCurrentIndex(qMax(0, links.size() - 1));
......
......@@ -134,7 +134,7 @@ void HDDisplay::paintGL()
for (int i = 0; i < acceptList->size(); ++i)
{
QString value = acceptList->at(i);
drawGauge(xCoord, yCoord, gaugeWidth/2.0f, minValues.value(value, 0.0f), maxValues.value(value, 1.0f), value, values.value(value, minValues.value(value, 0.0f)), gaugeColor, &painter, goodRanges.value(value, qMakePair(0.0f, 0.5f)), critRanges.value(value, qMakePair(0.7f, 1.0f)), true);
drawGauge(xCoord, yCoord, gaugeWidth/2.0f, minValues.value(value, -1.0f), maxValues.value(value, 1.0f), value, values.value(value, minValues.value(value, 0.0f)), gaugeColor, &painter, goodRanges.value(value, qMakePair(0.0f, 0.5f)), critRanges.value(value, qMakePair(0.7f, 1.0f)), true);
xCoord += gaugeWidth + leftSpacing;
// Move one row down if necessary
if (xCoord + gaugeWidth > vwidth)
......@@ -511,8 +511,8 @@ float HDDisplay::refLineWidthToPen(float line)
void HDDisplay::updateValue(UASInterface* uas, QString name, double value, quint64 msec)
{
if (this->uas == uas)
{
//if (this->uas == uas)
//{
// Update mean
const float oldMean = valuesMean.value(name, 0.0f);
const int meanCount = valuesCount.value(name, 0);
......@@ -521,7 +521,7 @@ void HDDisplay::updateValue(UASInterface* uas, QString name, double value, quint
valuesDot.insert(name, (value - values.value(name, 0.0f)) / ((msec - lastUpdate.value(name, 0))/1000.0f));
values.insert(name, value);
lastUpdate.insert(name, msec);
}
//}
}
/**
......
......@@ -80,23 +80,23 @@ protected:
void drawSystemIndicator(float xRef, float yRef, int maxNum, float maxWidth, float maxHeight, QPainter* painter);
void paintText(QString text, QColor color, float fontSize, float refX, float refY, QPainter* painter);
UASInterface* uas; ///< The uas currently monitored
QMap<QString, float> values; ///< The variables this HUD displays
QMap<QString, float> valuesDot; ///< First derivative of the variable
QMap<QString, float> valuesMean; ///< Mean since system startup for this variable
QMap<QString, int> valuesCount; ///< Number of values received so far
UASInterface* uas; ///< The uas currently monitored
QMap<QString, float> values; ///< The variables this HUD displays
QMap<QString, float> valuesDot; ///< First derivative of the variable
QMap<QString, float> valuesMean; ///< Mean since system startup for this variable
QMap<QString, int> valuesCount; ///< Number of values received so far
QMap<QString, quint64> lastUpdate; ///< The last update time for this variable
QMap<QString, float> minValues; ///< The minimum value this variable is assumed to have
QMap<QString, float> maxValues; ///< The maximum value this variable is assumed to have
QMap<QString, float> minValues; ///< The minimum value this variable is assumed to have
QMap<QString, float> maxValues; ///< The maximum value this variable is assumed to have
QMap<QString, QPair<float, float> > goodRanges; ///< The range of good values
QMap<QString, QPair<float, float> > critRanges; ///< The range of critical values
double scalingFactor; ///< Factor used to scale all absolute values to screen coordinates
double scalingFactor; ///< Factor used to scale all absolute values to screen coordinates
float xCenterOffset, yCenterOffset; ///< Offset from center of window in mm coordinates
float vwidth; ///< Virtual width of this window, 200 mm per default. This allows to hardcode positions and aspect ratios. This virtual image plane is then scaled to the window size.
float vheight; ///< Virtual height of this window, 150 mm per default
float vwidth; ///< Virtual width of this window, 200 mm per default. This allows to hardcode positions and aspect ratios. This virtual image plane is then scaled to the window size.
float vheight; ///< Virtual height of this window, 150 mm per default
int xCenter; ///< Center of the HUD instrument in pixel coordinates. Allows to off-center the whole instrument in its OpenGL window, e.g. to fit another instrument
int yCenter; ///< Center of the HUD instrument in pixel coordinates. Allows to off-center the whole instrument in its OpenGL window, e.g. to fit another instrument
int xCenter; ///< Center of the HUD instrument in pixel coordinates. Allows to off-center the whole instrument in its OpenGL window, e.g. to fit another instrument
int yCenter; ///< Center of the HUD instrument in pixel coordinates. Allows to off-center the whole instrument in its OpenGL window, e.g. to fit another instrument
// HUD colors
QColor backgroundColor; ///< Background color
......
......@@ -45,7 +45,7 @@ This file is part of the PIXHAWK project
template<typename T>
inline bool isnan(T value)
{
return value != value;
return value != value;
}
......@@ -65,48 +65,48 @@ inline bool isinf(T value)
* @param parent
*/
HUD::HUD(int width, int height, QWidget* parent)
: QGLWidget(parent),
uas(NULL),
values(QMap<QString, float>()),
valuesDot(QMap<QString, float>()),
valuesMean(QMap<QString, float>()),
valuesCount(QMap<QString, int>()),
lastUpdate(QMap<QString, quint64>()),
yawInt(0.0f),
mode(tr("UNKNOWN MODE")),
state(tr("UNKNOWN STATE")),
fuelStatus(tr("00.0V (00m:00s)")),
xCenterOffset(0.0f),
yCenterOffset(0.0f),
vwidth(200.0f),
vheight(150.0f),
vGaugeSpacing(50.0f),
vPitchPerDeg(6.0f), ///< 4 mm y translation per degree)
rawBuffer1(NULL),
rawBuffer2(NULL),
rawImage(NULL),
rawLastIndex(0),
rawExpectedBytes(0),
bytesPerLine(1),
imageStarted(false),
receivedDepth(8),
receivedChannels(1),
receivedWidth(640),
receivedHeight(480),
defaultColor(QColor(70, 200, 70)),
setPointColor(QColor(200, 20, 200)),
warningColor(Qt::yellow),
criticalColor(Qt::red),
infoColor(QColor(20, 200, 20)),
fuelColor(criticalColor),
warningBlinkRate(5),
refreshTimer(new QTimer(this)),
noCamera(true),
hardwareAcceleration(true),
strongStrokeWidth(1.5f),
normalStrokeWidth(1.0f),
fineStrokeWidth(0.5f),
waypointName("")
: QGLWidget(parent),
uas(NULL),
values(QMap<QString, float>()),
valuesDot(QMap<QString, float>()),
valuesMean(QMap<QString, float>()),
valuesCount(QMap<QString, int>()),
lastUpdate(QMap<QString, quint64>()),
yawInt(0.0f),
mode(tr("UNKNOWN MODE")),
state(tr("UNKNOWN STATE")),
fuelStatus(tr("00.0V (00m:00s)")),
xCenterOffset(0.0f),
yCenterOffset(0.0f),
vwidth(200.0f),
vheight(150.0f),
vGaugeSpacing(50.0f),
vPitchPerDeg(6.0f), ///< 4 mm y translation per degree)
rawBuffer1(NULL),
rawBuffer2(NULL),
rawImage(NULL),
rawLastIndex(0),
rawExpectedBytes(0),
bytesPerLine(1),
imageStarted(false),
receivedDepth(8),
receivedChannels(1),
receivedWidth(640),
receivedHeight(480),
defaultColor(QColor(70, 200, 70)),
setPointColor(QColor(200, 20, 200)),
warningColor(Qt::yellow),
criticalColor(Qt::red),
infoColor(QColor(20, 200, 20)),
fuelColor(criticalColor),
warningBlinkRate(5),
refreshTimer(new QTimer(this)),
noCamera(true),
hardwareAcceleration(true),
strongStrokeWidth(1.5f),
normalStrokeWidth(1.0f),
fineStrokeWidth(0.5f),
waypointName("")
{
// Set auto fill to false
setAutoFillBackground(false);
......@@ -171,8 +171,9 @@ void HUD::stop()
void HUD::updateValue(UASInterface* uas, QString name, double value, quint64 msec)
{
// if (this->uas == uas)
// if (this->uas == uas)
//{
if (!isnan(value) && !isinf(value))
{
// Update mean
......@@ -184,11 +185,14 @@ void HUD::updateValue(UASInterface* uas, QString name, double value, quint64 mse
valuesCount.insert(name, meanCount + 1);
// Two-value sliding average
double dot = (valuesDot.value(name) + (value - values.value(name, 0.0f)) / ((msec - lastUpdate.value(name, 0))/1000.0f))/2.0f;
if (isnan(dot) || isinf(dot)) dot = 0.0;
if (isnan(dot) || isinf(dot))
{
dot = 0.0;
}
valuesDot.insert(name, dot);
values.insert(name, value);
lastUpdate.insert(name, msec);
//}
//}
//qDebug() << __FILE__ << __LINE__ << "VALUE:" << value << "MEAN:" << mean << "DOT:" << dot << "COUNT:" << meanCount;
}
......@@ -211,7 +215,8 @@ void HUD::setActiveUAS(UASInterface* uas)
disconnect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateLocalPosition(UASInterface*,double,double,double,quint64)));
disconnect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64)));
disconnect(uas, SIGNAL(speedChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateSpeed(UASInterface*,double,double,double,quint64)));
disconnect(uas, SIGNAL(statusChanged(UASInterface*,QString,QString)), this, SLOT(updateState(UASInterface*,QString,QString)));
disconnect(uas, SIGNAL(statusChanged(UASInterface*,QString,QString)), this, SLOT(updateState(UASInterface*,QString)));
disconnect(uas, SIGNAL(modeChanged(UASInterface*,QString,QString)), this, SLOT(updateMode(UASInterface*,QString)));
disconnect(uas, SIGNAL(loadChanged(UASInterface*, double)), this, SLOT(updateLoad(UASInterface*, double)));
disconnect(uas, SIGNAL(attitudeThrustSetPointChanged(UASInterface*,double,double,double,double,quint64)), this, SLOT(updateAttitudeThrustSetPoint(UASInterface*,double,double,double,double,quint64)));
disconnect(uas, SIGNAL(valueChanged(UASInterface*,QString,double,quint64)), this, SLOT(updateValue(UASInterface*,QString,double,quint64)));
......@@ -247,6 +252,7 @@ void HUD::updateAttitudeThrustSetPoint(UASInterface*, double rollDesired, double
void HUD::updateAttitude(UASInterface* uas, double roll, double pitch, double yaw, quint64 timestamp)
{
//qDebug() << __FILE__ << __LINE__ << "ROLL" << roll;
updateValue(uas, "roll", roll, timestamp);
updateValue(uas, "pitch", pitch, timestamp);
updateValue(uas, "yaw", yaw, timestamp);
......@@ -307,14 +313,21 @@ void HUD::updateSpeed(UASInterface* uas,double x,double y,double z,quint64 times
*
* @param uas the system the state message originates from
* @param state short state text, displayed in HUD
* @param description longer state text, currently unused
*/
void HUD::updateState(UASInterface* uas,QString state, QString description)
void HUD::updateState(UASInterface* uas,QString state)
{
if (this->uas == uas)
{
this->state = state;
}
this->state = state;
}
/**
* Updates the current system mode, but only if the uas matches the currently monitored uas.
*
* @param uas the system the state message originates from
* @param mode short mode text, displayed in HUD
*/
void HUD::updateMode(UASInterface* uas,QString mode)
{
this->mode = mode;
}
void HUD::updateLoad(UASInterface* uas, double load)
......@@ -501,9 +514,9 @@ void HUD::paintRollPitchStrips()
void HUD::paintGL()
{
// Read out most important values to limit hash table lookups
static float roll = roll * 0.5 + 0.5 * values.value("roll", 0.0f);
static float pitch = pitch * 0.5 + 0.5 * values.value("pitch", 0.0f);
static float yaw = yaw * 0.5 + 0.5 * values.value("yaw", 0.0f);
float roll = roll * 0.5 + 0.5 * values.value("roll", 0.0f);
float pitch = pitch * 0.5 + 0.5 * values.value("pitch", 0.0f);
float yaw = yaw * 0.5 + 0.5 * values.value("yaw", 0.0f);
//qDebug() << __FILE__ << __LINE__ << "ROLL:" << roll << "PITCH:" << pitch << "YAW:" << yaw;
......@@ -557,7 +570,8 @@ void HUD::paintGL()
// Position the coordinate frame according to the setup
QPainter painter(this);
painter.setRenderHint(QPainter::HighQualityAntialiasing);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
painter.translate((this->vwidth/2.0+xCenterOffset)*scalingFactor, (this->vheight/2.0+yCenterOffset)*scalingFactor);
// COORDINATE FRAME IS NOW (0,0) at CENTER OF WIDGET
......@@ -566,8 +580,10 @@ void HUD::paintGL()
// Draw all fixed indicators
// MODE
paintText(mode, infoColor, 2.0f, (-vwidth/2.0) + 10, -vheight/2.0 + 10, &painter);
// STATE
paintText(state, infoColor, 2.0f, (-vwidth/2.0) + 10, -vheight/2.0 + 15, &painter);
// BATTERY
paintText(fuelStatus, fuelColor, 2.0f, (-vwidth/2.0) + 10, -vheight/2.0 + 15, &painter);
paintText(fuelStatus, fuelColor, 2.0f, (-vwidth/2.0) + 10, -vheight/2.0 + 20, &painter);
// Waypoint
paintText(waypointName, defaultColor, 2.0f, (-vwidth/3.0) + 10, +vheight/3.0 + 15, &painter);
......@@ -659,13 +675,17 @@ void HUD::paintGL()
yawInt *= 0.6f;
//qDebug() << "yaw translation" << yawTrans << "integral" << yawInt << "difference" << yawDiff << "yaw" << yaw << "asin(yawInt)" << asinYaw;
painter.translate(0, (pitch/M_PI)* -180.0f * refToScreenY(2.0f));
painter.translate(refToScreenX(yawTrans), 0);
painter.translate(0, (pitch/M_PI)* -180.0f * refToScreenY(2.0f));
// Rotate view and draw all roll-dependent indicators
painter.rotate((roll/M_PI)* -180.0f);
qDebug() << "ROLL" << roll << "PITCH" << pitch << "YAW DIFF" << valuesDot.value("roll", 0.0f);
// CENTER
// SETPOINT
......
......@@ -79,7 +79,8 @@ public slots:
void updateLocalPosition(UASInterface*,double,double,double,quint64);
void updateGlobalPosition(UASInterface*,double,double,double,quint64);
void updateSpeed(UASInterface*,double,double,double,quint64);
void updateState(UASInterface*,QString,QString);
void updateState(UASInterface*,QString);
void updateMode(UASInterface*,QString);
void updateLoad(UASInterface*, double);
void selectWaypoint(UASInterface* uas, int id);
......
......@@ -27,7 +27,9 @@ void JoystickWidget::updateJoystick(double roll, double pitch, double yaw, doubl
{
setX(roll);
setY(pitch);
setZ(yaw);
setThrottle(thrust);
setHat(xHat, yHat);
}
void JoystickWidget::changeEvent(QEvent *e)
......@@ -46,16 +48,29 @@ void JoystickWidget::setThrottle(float thrust)
{
m_ui->thrust->setValue(thrust*100);
}
void JoystickWidget::setX(float x)
{
m_ui->xSlider->setValue(x*100);
m_ui->xValue->display(x*100);
}
void JoystickWidget::setY(float y)
{
m_ui->ySlider->setValue(y*100);
m_ui->yValue->display(y*100);
}
void JoystickWidget::setZ(float z)
{
m_ui->dial->setValue(z*100);
}
void JoystickWidget::setHat(float x, float y)
{
qDebug() << __FILE__ << __LINE__ << "HAT X:" << x << "HAT Y:" << y;
}
void JoystickWidget::pressKey(int key)
{
QString colorstyle;
......@@ -64,5 +79,5 @@ void JoystickWidget::pressKey(int key)
heartbeatColor.red(), heartbeatColor.green(), heartbeatColor.blue());
m_ui->button0Label->setStyleSheet(colorstyle);
m_ui->button0Label->setAutoFillBackground(true);
qDebug() << "KEY" << key << " pressed on joystick";
qDebug() << __FILE__ << __LINE__ << "KEY" << key << " pressed on joystick";
}
......@@ -23,7 +23,7 @@ This file is part of the PIXHAWK project
/**
* @file
* @brief Definition of joystick interface
* @brief Definition of joystick widget
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
......@@ -57,14 +57,23 @@ public:
* @param yHat hat vector in left-right direction, -1 left, 0 center, +1 right
*/
void updateJoystick(double roll, double pitch, double yaw, double thrust, int xHat, int yHat);
/** @brief Throttle lever */
void setThrottle(float thrust);
/** @brief Back/forth movement */
void setX(float x);
/** @brief Left/right movement */
void setY(float y);
/** @brief Wrist rotation */
void setZ(float z);
/** @brief Hat switch position */
void setHat(float x, float y);
/** @brief Joystick keys, as labeled on the joystick */
void pressKey(int key);
protected:
/** @brief UI change event */
virtual void changeEvent(QEvent *e);
JoystickInput* joystick;
JoystickInput* joystick; ///< Reference to the joystick
private:
Ui::JoystickWidget *m_ui;
......
......@@ -45,6 +45,7 @@ This file is part of the PIXHAWK project
#include "WaypointList.h"
#include "MainWindow.h"
#include "JoystickWidget.h"
#include "GAudioOutput.h"
#include "LogCompressor.h"
......@@ -56,7 +57,7 @@ This file is part of the PIXHAWK project
*
* @see QMainWindow::show()
**/
MGMainWindow::MGMainWindow(QWidget *parent) : QMainWindow(parent)
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
// Quick hack
......@@ -167,20 +168,20 @@ MGMainWindow::MGMainWindow(QWidget *parent) : QMainWindow(parent)
udpLink->connect();
simulationLink = new MAVLinkSimulationLink(MG::DIR::getSupportFilesDirectory() + "/demo-log.txt");
connect(simulationLink, SIGNAL(valueChanged(int,QString,double,quint64)), linechart, SLOT(appendData(int,QString,double,quint64)));
//connect(simulationLink, SIGNAL(valueChanged(int,QString,double,quint64)), linechart, SLOT(appendData(int,QString,double,quint64)));
LinkManager::instance()->addProtocol(simulationLink, mavlink);
//CommConfigurationWindow* simulationWidget = new CommConfigurationWindow(simulationLink, mavlink, this);
//ui.menuNetwork->addAction(commWidget->getAction());
simulationLink->connect();
}
MGMainWindow::~MGMainWindow()
MainWindow::~MainWindow()
{
delete statusBar;
statusBar = NULL;
}
QStatusBar* MGMainWindow::createStatusBar()
QStatusBar* MainWindow::createStatusBar()
{
QStatusBar* bar = new QStatusBar();
/* Add status fields and messages */
......@@ -189,7 +190,7 @@ QStatusBar* MGMainWindow::createStatusBar()
return bar;
}
void MGMainWindow::startVideoCapture()
void MainWindow::startVideoCapture()
{
QString format = "bmp";
QString initialPath = QDir::currentPath() + tr("/untitled.") + format;
......@@ -205,14 +206,14 @@ void MGMainWindow::startVideoCapture()
connect(videoTimer, SIGNAL(timeout()), this, SLOT(saveScreen()));
}
void MGMainWindow::stopVideoCapture()
void MainWindow::stopVideoCapture()
{
videoTimer->stop();
// TODO Convert raw images to PNG
}
void MGMainWindow::saveScreen()
void MainWindow::saveScreen()
{
QPixmap window = QPixmap::grabWindow(this->winId());
QString format = "bmp";
......@@ -223,7 +224,7 @@ void MGMainWindow::saveScreen()
}
}
void MGMainWindow::reloadStylesheet()
void MainWindow::reloadStylesheet()
{
// Load style sheet
//QFile styleSheet(MG::DIR::getSupportFilesDirectory() + "/images/style-mission.css");
......@@ -237,17 +238,17 @@ void MGMainWindow::reloadStylesheet()
}
}
void MGMainWindow::showStatusMessage(const QString& status, int timeout)
void MainWindow::showStatusMessage(const QString& status, int timeout)
{
statusBar->showMessage(status, timeout);
}
void MGMainWindow::setLastAction(QString status)
void MainWindow::setLastAction(QString status)
{
showStatusMessage(status, 5);
}
void MGMainWindow::setLinkStatus(QString status)
void MainWindow::setLinkStatus(QString status)
{
showStatusMessage(status, 15);
}
......@@ -256,7 +257,7 @@ void MGMainWindow::setLinkStatus(QString status)
* @brief Create all actions associated to the main window
*
**/
void MGMainWindow::connectActions()
void MainWindow::connectActions()
{
// Connect actions from ui
connect(ui.actionAdd_Link, SIGNAL(triggered()), this, SLOT(addLink()));
......@@ -283,12 +284,12 @@ void MGMainWindow::connectActions()
connect(ui.actionJoystickSettings, SIGNAL(triggered()), this, SLOT(configure()));
}
void MGMainWindow::configure()
void MainWindow::configure()
{
joystickWidget = new JoystickWidget(joystick, this);
}
void MGMainWindow::addLink()
void MainWindow::addLink()
{
SerialLink* link = new SerialLink();
// TODO This should be only done in the dialog itself
......@@ -304,13 +305,19 @@ void MGMainWindow::addLink()
// TODO Implement the link removal!
}
void MGMainWindow::UASCreated(UASInterface* uas)
void MainWindow::UASCreated(UASInterface* uas)
{
// Connect the UAS to the full user interface
ui.menuConnected_Systems->addAction(QIcon(":/actions/linechart.svg"), tr("View ") + uas->getUASName(), uas, SLOT(setSelected()));
ui.menuConnected_Systems->addAction(QIcon(":/images/mavs/generic.svg"), tr("View ") + uas->getUASName(), uas, SLOT(setSelected()));
// Line chart
connect(uas, SIGNAL(valueChanged(int,QString,double,quint64)), linechart, SLOT(appendData(int,QString,double,quint64)), Qt::QueuedConnection);
// FIXME DO THIS ONLY FOR THE FIRST CONNECTED SYSTEM
static bool sysPresent = false;
if (!sysPresent)
{
connect(uas, SIGNAL(valueChanged(int,QString,double,quint64)), linechart, SLOT(appendData(int,QString,double,quint64)), Qt::QueuedConnection);
sysPresent = true;
}
// Health / System status indicator
info->addUAS(uas);
......@@ -326,12 +333,12 @@ void MGMainWindow::UASCreated(UASInterface* uas)
reloadStylesheet();
}
void MGMainWindow::clearView()
void MainWindow::clearView()
{
// Halt HUD
hud->stop();
/*headDown1->stop();
headDown2->stop();*/
headDown1->stop();
headDown2->stop();
// Remove all dock widgets
QList<QObject*> list = this->children();
......@@ -352,9 +359,10 @@ void MGMainWindow::clearView()
}
}
void MGMainWindow::loadPilotView()
void MainWindow::loadPilotView()
{
clearView();
GAudioOutput::instance()->say("Switched to Pilot View");
// HEAD UP DISPLAY
centerStack->setCurrentWidget(hud);
......@@ -376,10 +384,12 @@ void MGMainWindow::loadPilotView()
this->show();
}
void MGMainWindow::loadOperatorView()
void MainWindow::loadOperatorView()
{
clearView();
GAudioOutput::instance()->say("Switched to Operator View");
// LINE CHART
centerStack->setCurrentWidget(map);
......@@ -416,10 +426,12 @@ void MGMainWindow::loadOperatorView()
this->show();
}
void MGMainWindow::loadSettingsView()
void MainWindow::loadSettingsView()
{
clearView();
GAudioOutput::instance()->say("Switched to Settings View");
// LINE CHART
centerStack->setCurrentWidget(linechart);
......@@ -434,11 +446,13 @@ void MGMainWindow::loadSettingsView()
addDockWidget(Qt::RightDockWidgetArea, container6);
}
void MGMainWindow::loadEngineerView()
void MainWindow::loadEngineerView()
{
clearView();
// Engineer view, used in EMAV2009
GAudioOutput::instance()->say("Switched to Engineer View");
// LINE CHART
centerStack->setCurrentWidget(linechart);
......@@ -470,7 +484,7 @@ void MGMainWindow::loadEngineerView()
this->show();
}
void MGMainWindow::loadWidgets()
void MainWindow::loadWidgets()
{
loadOperatorView();
//loadEngineerView();
......@@ -478,32 +492,32 @@ void MGMainWindow::loadWidgets()
}
/*
void MGMainWindow::removeCommConfAct(QAction* action)
void MainWindow::removeCommConfAct(QAction* action)
{
ui.menuNetwork->removeAction(action);
}*/
//void MGMainWindow::startUAS()
//void MainWindow::startUAS()
//{
// UASManager::instance()->getActiveUAS()->launch();
//}
//
//void MGMainWindow::returnUAS()
//void MainWindow::returnUAS()
//{
// UASManager::instance()->getActiveUAS()->home();
//}
//
//void MGMainWindow::stopUAS()
//void MainWindow::stopUAS()
//{
// UASManager::instance()->getActiveUAS()->emergencySTOP();
//}
//
//void MGMainWindow::killUAS()
//void MainWindow::killUAS()
//{
// UASManager::instance()->getActiveUAS()->emergencyKILL();
//}
void MGMainWindow::runTests()
void MainWindow::runTests()
{
// TODO Remove after debugging: Add fake data
static double testvalue = 0.0f;
......
......@@ -67,12 +67,12 @@ This file is part of the PIXHAWK project
* @brief Main Application Window
*
**/
class MGMainWindow : public QMainWindow {
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MGMainWindow(QWidget *parent = 0);
~MGMainWindow();
MainWindow(QWidget *parent = 0);
~MainWindow();
UASControlWidget* control;
LinechartWidget* linechart;
......@@ -161,7 +161,7 @@ protected:
QTimer* videoTimer;
private:
Ui::MGMainWindow ui;
Ui::MainWindow ui;
};
#endif /* _MAINWINDOW_H_ */
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MGMainWindow</class>
<widget class="QMainWindow" name="MGMainWindow">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
......@@ -241,7 +241,7 @@
<connection>
<sender>actionExit</sender>
<signal>triggered()</signal>
<receiver>MGMainWindow</receiver>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
......
......@@ -29,14 +29,55 @@
<string>QWidget#colorIcon {}
QWidget {
background-color: #252528;
background-color: none;
color: #DDDDDF;
border-color: #EEEEEE;
background-clip: margin;
}
QLabel#nameLabel {
font: bold 16px;
color: #3C7B9E;
}
QLabel#modeLabel {
font: 12px;
}
QLabel#stateLabel {
font: 12px;
}
QLabel#gpsLabel {
font: 8px;
}
QLabel#positionLabel {
font: 8px;
}
QLabel#timeElapsedLabel {
font: 8px;
}
QLabel#groundDistanceLabel {
font: 8px;
}
QLabel#speedLabel {
font: 8px;
}
QLabel#timeRemainingLabel {
font: 8px;
}
QLabel#waypointLabel {
font: 24px;
}
QGroupBox {
border: 1px solid #EEEEEE;
border: 1px solid #4A4A4F;
border-radius: 5px;
padding: 0px 0px 0px 0px;
margin: 0px;
......@@ -67,6 +108,19 @@ QToolButton {
background-color: none;
}
QToolButton#typeButton {
font-weight: bold;
font-size: 12px;
border: 2px solid #999999;
border-radius: 5px;
min-width:44px;
max-width: 44px;
min-height: 44px;
max-height: 44px;
padding: 0px;
background-color: none;
}
QPushButton {
font-weight: bold;
font-size: 12px;
......@@ -84,41 +138,38 @@ QPushButton:pressed {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #444444, stop: 1 #555555);
}
QPushButton#landButton {
color: #000000;
QPushButton#abortButton {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #ffee01, stop:1 #ae8f00) url(&quot;ICONDIR/control/emergency-button.png&quot;);
stop:0 #ffee01, stop:1 #ae8f00);
}
QPushButton:pressed#landButton {
color: #000000;
QPushButton:pressed#abortButton {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #bbaa00, stop:1 #a05b00) url(&quot;ICONDIR/control/emergency-button.png&quot;);
stop:0 #bbaa00, stop:1 #a05b00);
}
QPushButton#killButton {
color: #000000;
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #ffb917, stop:1 #b37300) url(&quot;ICONDIR/control/emergency-button.png&quot;);
stop:0 #ffb917, stop:1 #b37300);
}
QPushButton:pressed#killButton {
color: #000000;
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #bb8500, stop:1 #903000) url(&quot;ICONDIR/control/emergency-button.png&quot;);
stop:0 #bb8500, stop:1 #903000);
}
QProgressBar {
border: 1px solid white;
border: 1px solid #4A4A4F;
border-radius: 4px;
text-align: center;
padding: 2px;
color: white;
background-color: #111111;
color: #DDDDDF;
background-color: #111118;
}
QProgressBar:horizontal {
height: 12px;
height: 10px;
}
QProgressBar QLabel {
......@@ -180,14 +231,14 @@ QProgressBar::chunk#thrustBar {
<widget class="QToolButton" name="typeButton">
<property name="minimumSize">
<size>
<width>46</width>
<height>46</height>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>46</width>
<height>46</height>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="baseSize">
......@@ -234,8 +285,9 @@ QProgressBar::chunk#thrustBar {
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
<pointsize>-1</pointsize>
<weight>75</weight>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
......@@ -254,8 +306,9 @@ QProgressBar::chunk#thrustBar {
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
<pointsize>-1</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
......@@ -268,7 +321,10 @@ QProgressBar::chunk#thrustBar {
<widget class="QLabel" name="timeRemainingLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
<pointsize>-1</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
......@@ -280,7 +336,10 @@ QProgressBar::chunk#thrustBar {
<widget class="QLabel" name="timeElapsedLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
<pointsize>-1</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
......@@ -304,7 +363,10 @@ QProgressBar::chunk#thrustBar {
<widget class="QLabel" name="groundDistanceLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
<pointsize>-1</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
......@@ -313,14 +375,17 @@ QProgressBar::chunk#thrustBar {
</widget>
</item>
<item row="4" column="4" colspan="2">
<widget class="QLabel" name="altitudeLabel">
<widget class="QLabel" name="speedLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
<pointsize>-1</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>00.00 m</string>
<string>00.0 m/s</string>
</property>
</widget>
</item>
......@@ -380,9 +445,10 @@ QProgressBar::chunk#thrustBar {
<widget class="QLabel" name="stateLabel">
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
<pointsize>-1</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
......@@ -394,14 +460,18 @@ QProgressBar::chunk#thrustBar {
<widget class="QLabel" name="waypointLabel">
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
<pointsize>-1</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>WPX</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="2" column="6">
......@@ -420,7 +490,10 @@ QProgressBar::chunk#thrustBar {
</property>
<property name="font">
<font>
<pointsize>8</pointsize>
<pointsize>-1</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
......@@ -444,7 +517,10 @@ QProgressBar::chunk#thrustBar {
</property>
<property name="font">
<font>
<pointsize>8</pointsize>
<pointsize>-1</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
......@@ -530,7 +606,7 @@ QProgressBar::chunk#thrustBar {
</widget>
</item>
<item>
<widget class="QPushButton" name="returnButton">
<widget class="QPushButton" name="landButton">
<property name="minimumSize">
<size>
<width>18</width>
......@@ -553,12 +629,12 @@ QProgressBar::chunk#thrustBar {
</property>
<property name="icon">
<iconset resource="../../mavground.qrc">
<normaloff>:/images/actions/go-home.svg</normaloff>:/images/actions/go-home.svg</iconset>
<normaloff>:/images/actions/system-log-out.svg</normaloff>:/images/actions/system-log-out.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="landButton">
<widget class="QPushButton" name="abortButton">
<property name="minimumSize">
<size>
<width>18</width>
......
......@@ -73,8 +73,8 @@ UASView::UASView(UASInterface* uas, QWidget *parent) :
connect(m_ui->liftoffButton, SIGNAL(clicked()), uas, SLOT(launch()));
connect(m_ui->haltButton, SIGNAL(clicked()), uas, SLOT(halt()));
connect(m_ui->continueButton, SIGNAL(clicked()), uas, SLOT(go()));
connect(m_ui->returnButton, SIGNAL(clicked()), uas, SLOT(home()));
connect(m_ui->landButton, SIGNAL(clicked()), uas, SLOT(emergencySTOP()));
connect(m_ui->landButton, SIGNAL(clicked()), uas, SLOT(home()));
connect(m_ui->abortButton, SIGNAL(clicked()), uas, SLOT(emergencySTOP()));
connect(m_ui->killButton, SIGNAL(clicked()), uas, SLOT(emergencyKILL()));
connect(m_ui->shutdownButton, SIGNAL(clicked()), uas, SLOT(shutdown()));
......@@ -95,6 +95,15 @@ UASView::UASView(UASInterface* uas, QWidget *parent) :
//m_ui->speedBar->setMinimum(0);
//m_ui->speedBar->setMaximum(15);
// UAS color
QColor uasColor = uas->getColor();
uasColor = uasColor.darker(475);
QString colorstyle;
colorstyle = colorstyle.sprintf("QGroupBox { border: 2px solid #4A4A4F; border-radius: 5px; padding: 0px; margin: 0px; background-color: #%02X%02X%02X;}",
uasColor.red(), uasColor.green(), uasColor.blue());
m_ui->groupBox->setStyleSheet(colorstyle);
//m_ui->groupBox->setAutoFillBackground(true);
// Heartbeat fade
refreshTimer = new QTimer(this);
......@@ -107,6 +116,11 @@ UASView::~UASView()
delete m_ui;
}
void UASView::setUASasActive(bool)
{
UASManager::instance()->setActiveUAS(this->uas);
}
void UASView::updateMode(int sysId, QString status, QString description)
{
if (sysId == this->uas->getUASID()) m_ui->modeLabel->setText(status);
......@@ -182,13 +196,6 @@ void UASView::setSystemType(UASInterface* uas, unsigned int systemType)
break;
}
}
// MAV_GENERIC = 0,
// MAV_FIXED_WING,
// MAV_QUADROTOR,
// MAV_COAXIAL,
// MAV_HELICOPTER,
// MAV_GROUND,
// OCU
}
void UASView::updateLocalPosition(UASInterface* uas, double x, double y, double z, quint64 usec)
......
......@@ -67,6 +67,8 @@ public slots:
void selectWaypoint(int uasId, int id);
/** @brief Set the current system type */
void setSystemType(UASInterface* uas, unsigned int systemType);
/** @brief Set the current UAS as the globally active system */
void setUASasActive(bool);
protected:
void changeEvent(QEvent *e);
......
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