Commit bc33da52 authored by pixhawk's avatar pixhawk

Added true audio output

parent 124997d0
File added
# 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
# 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 \
src/comm/ViconTarsusProtocol.h \
src/comm/TarsusField.h \
src/comm/TarsusFieldDescriptor.h \
src/comm/TarsusFieldTriplet.h \
src/comm/TarsusRigidBody.h \
src/comm/TarsusStream.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 \
src/comm/ViconTarsusProtocol.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(lib/QMapControl/QMapControl.pri)
DEPENDPATH += . \
lib/QMapControl \
lib/QMapControl/src
INCLUDEPATH += . \
lib/QMapControl \
../mavlink/src \
mavlink/src \
src/mavlink
# 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>
#include "AudioOutput.h"
#include <flite.h>
#include <phonon/mediaobject.h>
#include <QTemporaryFile>
#include <QDebug>
extern "C" {
#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);
};
AudioOutput::AudioOutput(QString voice, QObject* parent) : QObject(parent),
voice(NULL),
voiceIndex(0)
{
#ifndef _WIN32
flite_init();
#endif
switch (voiceIndex)
{
case 0:
selectFemaleVoice();
break;
case 1:
selectMaleVoice();
break;
default:
selectNeutralVoice();
break;
}
/*
// List available voices
QStringList voices = listVoices();
foreach (QString s, voices)
{
qDebug() << "VOICE: " << s;
}
if (voice.length() > 0)
{
//this->voice = flite_voice_select(voice.toStdString().c_str());
}
else
{
// Take default voice
//this->voice = flite_voice_select("awb");
}
*/
}
bool AudioOutput::say(QString text, int severity)
{
// Only give speech output on Linux and MacOS
#ifndef _WIN32
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");
Phonon::MediaObject *music =
Phonon::createPlayer(Phonon::MusicCategory,
Phonon::MediaSource(file.fileName().toStdString().c_str()));
music->play();
qDebug() << "Synthesized: " << text << ", tmp file:" << file.fileName().toStdString().c_str();
}
#else
qDebug() << "Synthesized: " << text << ", NO OUTPUT SUPPORT ON WINDOWS!";
#endif
return true;
}
bool AudioOutput::alert(QString text)
{
// Play alert sound
// Say alert message
return say(text, 2);
}
bool AudioOutput::startEmergency()
{
return false;
}
bool AudioOutput::stopEmergency()
{
return false;
}
void AudioOutput::selectFemaleVoice()
{
#ifndef _WIN32
this->voice = register_cmu_us_slt(NULL);
#endif
}
void AudioOutput::selectMaleVoice()
{
#ifndef _WIN32
this->voice = register_cmu_us_rms(NULL);
#endif
}
void AudioOutput::selectNeutralVoice()
{
#ifndef _WIN32
this->voice = register_cmu_us_awb(NULL);
#endif
}
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
QStringList AudioOutput::listVoices(void)
{
cst_voice *voice;
const cst_val *v;
QStringList l;
#ifndef _WIN32
/*
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 */
#ifndef AUDIOOUTPUT_H
#define AUDIOOUTPUT_H
#include <QObject>
#include <QStringList>
#include <flite.h>
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:
cst_voice* voice;
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");
......@@ -69,12 +69,12 @@ MGCore::MGCore(int &argc, char* argv[]) : QApplication(argc, argv)
QFontDatabase fontDatabase = QFontDatabase();
const QString fontFileName = ":/general/vera.ttf"; ///< Font file is part of the QRC file and compiled into the app
const QString fontFamilyName = "Bitstream Vera Sans";
if(!QFile::exists(fontFileName)) printf("ERROR! font file: %s DOES NOT EXIST!", fontFileName);
//if(!QFile::exists(fontFileName)) //printf("ERROR! font file: %s DOES NOT EXIST!", fontFileName);
fontDatabase.addApplicationFont(fontFileName);
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,11 +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();
//tarsus = new ViconTarsusProtocol();
//tarsus->start();
// Start the user interface
splashScreen->showMessage(tr("Starting User Interface"));
......@@ -107,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();
......@@ -120,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();
}
......@@ -129,7 +128,7 @@ void MGCore::startLinkManager()
* @brief Start the Unmanned Air System Manager
*
**/
void MGCore::startUASManager()
void Core::startUASManager()
{
UASManager::instance();
}
......@@ -137,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,15 +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"
/*#include "ViconTarsusProtocol.h" */
/**
* @brief The main application and management class.
......@@ -47,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();
......@@ -68,9 +68,9 @@ protected:
void startUI();
private:
MGMainWindow* mainWindow;
ViconTarsusProtocol* tarsus;
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 "GAudioOutput.h"
#include "MG.h"
#include <flite.h>
#include <Phonon>
#include <QTemporaryFile>
#include <QDebug>
extern "C" {
#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);
};
/**
* 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),
voice(NULL),
voiceIndex(0),
emergency(false)
{
#ifndef _WIN32
flite_init();
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()));
#endif
switch (voiceIndex)
{
case 0:
selectFemaleVoice();
break;
case 1:
selectMaleVoice();
break;
default:
selectNeutralVoice();
break;
}
/*
// List available voices
QStringList voices = listVoices();
foreach (QString s, voices)
{
qDebug() << "VOICE: " << s;
}
if (voice.length() > 0)
{
//this->voice = flite_voice_select(voice.toStdString().c_str());
}
else
{
// Take default voice
//this->voice = flite_voice_select("awb");
}
*/
}
bool GAudioOutput::say(QString text, int severity)
{
bool res = false;
if (!emergency)
{
// Only give speech output on Linux and MacOS
#ifndef _WIN32
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;
}
#else
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()
{
#ifndef _WIN32
this->voice = register_cmu_us_slt(NULL);
#endif
}
void GAudioOutput::selectMaleVoice()
{
#ifndef _WIN32
this->voice = register_cmu_us_rms(NULL);
#endif
}
void GAudioOutput::selectNeutralVoice()
{
#ifndef _WIN32
this->voice = register_cmu_us_awb(NULL);
#endif
}
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
QStringList GAudioOutput::listVoices(void)
{
cst_voice *voice;
const cst_val *v;
QStringList l;
#ifndef _WIN32
/*
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>
#include <flite.h>
#include <Phonon>
/**
* @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* 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:
cst_voice* voice; ///< The flite voice object
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
......
......@@ -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);
}
......
......@@ -43,6 +43,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);
......@@ -94,7 +97,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 +109,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 +117,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 +174,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 +252,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 +272,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 +493,10 @@ void UAS::receiveButton(int buttonIndex)
switch (buttonIndex)
{
case 0:
setAutoMode(false);
break;
case 1:
setAutoMode(true);
break;
default:
......@@ -631,7 +623,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));
......
......@@ -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