Commit 6344a49d authored by pixhawk's avatar pixhawk
Browse files

Added support for OSG on Mac platform

parents a1dc95ac fa827afc
This diff is collapsed.
......@@ -34,9 +34,17 @@ release {
# DEFINES += QT_NO_WARNING_OUTPUT
}
QMAKE_PRE_LINK += echo "Copying files"
#QMAKE_PRE_LINK += && cp -rf $$BASEDIR/models $$TARGETDIR/debug/.
#QMAKE_PRE_LINK += && cp -rf $$BASEDIR/models $$TARGETDIR/release/.
# MAC OS X
macx {
COMPILER_VERSION = $$system(gcc -v)
message(Using compiler $$COMPILER_VERSION)
HARDWARE_PLATFORM = $$system(uname -a)
contains( HARDWARE_PLATFORM, 9.6.0 ) || contains( HARDWARE_PLATFORM, 9.7.0 ) || contains( HARDWARE_PLATFORM, 9.8.0 ) || contains( HARDWARE_PLATFORM, 9.9.0 ) {
# x86 Mac OS X Leopard 10.5 and earlier
......@@ -55,18 +63,15 @@ macx {
message(Building for Mac OS X 64bit/Snow Leopard 10.6 and later)
}
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.5
DESTDIR = $$BASEDIR/bin/mac
INCLUDEPATH += -framework SDL \
$$BASEDIR/../mavlink/contrib/slugs/include \
$$BASEDIR/../mavlink/include
INCLUDEPATH += -framework SDL
LIBS += -framework IOKit \
-framework SDL \
-framework CoreFoundation \
-framework ApplicationServices \
# -framework GLUT \
-lm
ICON = $$BASEDIR/images/icons/macx.icns
......@@ -74,24 +79,67 @@ macx {
# Copy audio files if needed
QMAKE_PRE_LINK += cp -rf $$BASEDIR/audio $$DESTDIR/qgroundcontrol.app/Contents/MacOs/.
exists(/opt/local/lib/osg):exists("/opt/local/lib/osgEarth") {
message("Building support for OSGEARTH")
DEPENDENCIES_PRESENT += osgearth
LIBS += -L/opt/local/lib/
INCLUDEPATH += /opt/local/include
# Include OpenSceneGraph and osgEarth libraries
LIBS += -losg \
-losgViewer \
-losgEarth \
-losgEarthUtil
exists(/Library/Frameworks/osg.framework):exists(/Library/Frameworks/OpenThreads.framework) {
# No check for GLUT.framework since it's a MAC default
message("Building support for OpenSceneGraph")
DEPENDENCIES_PRESENT += osg
DEFINES += QGC_OSG_ENABLED
# Include OpenSceneGraph libraries
INCLUDEPATH += -framework GLUT \
-framework Carbon \
-framework OpenThreads \
-framework osg \
-framework osgViewer \
-framework osgGA \
-framework osgDB \
-framework osgText \
-framework osgWidget
LIBS += -framework GLUT \
-framework Carbon \
-framework OpenThreads \
-framework osg \
-framework osgViewer \
-framework osgGA \
-framework osgDB \
-framework osgText \
-framework osgWidget
}
exists(/usr/include/osgEarth) {
message("Building support for osgEarth")
DEPENDENCIES_PRESENT += osgearth
# Include osgEarth libraries
INCLUDEPATH += -framework GDAL \
$$IN_PWD/lib/mac32-gcc/include \
-framework GEOS \
-framework SQLite3 \
-framework osgFX \
-framework osgTerrain
LIBS += -framework GDAL \
-framework GEOS \
-framework SQLite3 \
-framework osgFX \
-framework osgTerrain \
DEFINES += QGC_OSGEARTH_ENABLED
}
exists(/opt/local/include/libfreenect) {
message("Building support for libfreenect")
DEPENDENCIES_PRESENT += libfreenect
# Include libfreenect libraries
LIBS += -lfreenect
DEFINES += QGC_LIBFREENECT_ENABLED
}
# osg/osgEarth dynamic casts might fail without this compiler option.
# see http://osgearth.org/wiki/FAQ for details.
#QMAKE_CXXFLAGS += -Wl, -E
}
# GNU/Linux
linux-g++ {
CONFIG += debug
debug {
DESTDIR = $$BUILDDIR/debug
......@@ -131,21 +179,41 @@ linux-g++ {
-lSDL \
-lSDLmain
exists(/usr/include/osgEarth) | exists(/usr/local/include/osgEarth) {
message("Building support for OSGEARTH")
DEPENDENCIES_PRESENT += osgearth
# Include OpenSceneGraph and osgEarth libraries
LIBS += -losg \
-losgViewer \
-losgEarth \
-losgEarthUtil
DEFINES += QGC_OSG_ENABLED
}
exists(/usr/include/osg) {
message("Building support for OpenSceneGraph")
DEPENDENCIES_PRESENT += osg
# Include OpenSceneGraph libraries
LIBS += -losg
DEFINES += QGC_OSG_ENABLED
}
QMAKE_CXXFLAGS += -Wl,-E
exists(/usr/include/osgEarth) | exists(/usr/local/include/osgEarth) {
message("Building support for osgEarth")
DEPENDENCIES_PRESENT += osgearth
# Include osgEarth libraries
LIBS += -losgViewer \
-losgEarth \
-losgEarthUtil
DEFINES += QGC_OSGEARTH_ENABLED
}
exists(/usr/local/include/libfreenect) {
message("Building suplocport for libfreenect")
DEPENDENCIES_PRESENT += libfreenect
INCLUDEPATH += /usr/include/libusb-1.0
# Include libfreenect libraries
LIBS += -lfreenect
DEFINES += QGC_LIBFREENECT_ENABLED
}
#-lflite_cmu_us_rms \
#-lflite_cmu_us_slt \
QMAKE_PRE_LINK += && cp -rf $$BASEDIR/models $$TARGETDIR/debug/.
QMAKE_PRE_LINK += && cp -rf $$BASEDIR/models $$TARGETDIR/release/.
QMAKE_PRE_LINK += && cp -rf $$BASEDIR/data $$TARGETDIR/debug/.
QMAKE_PRE_LINK += && cp -rf $$BASEDIR/data $$TARGETDIR/release/.
# osg/osgEarth dynamic casts might fail without this compiler option.
# see http://osgearth.org/wiki/FAQ for details.
QMAKE_CXXFLAGS += -Wl, -E
}
linux-g++-64 {
......@@ -188,16 +256,36 @@ linux-g++-64 {
-lSDL \
-lSDLmain
exists(/usr/lib/osg):exists(/usr/lib/osgEarth) {
message("Building support for OSGEARTH")
DEPENDENCIES_PRESENT += osgearth
# Include OpenSceneGraph and osgEarth libraries
LIBS += -losg \
-losgViewer \
-losgEarth
DEFINES += QGC_OSG_ENABLED
}
exists(/usr/include/osg) {
message("Building support for OpenSceneGraph")
DEPENDENCIES_PRESENT += osg
# Include OpenSceneGraph libraries
LIBS += -losg
DEFINES += QGC_OSG_ENABLED
}
exists(/usr/include/osgEarth) {
message("Building support for osgEarth")
DEPENDENCIES_PRESENT += osgearth
# Include osgEarth libraries
LIBS += -losgViewer \
-losgEarth \
-losgEarthUtil
DEFINES += QGC_OSGEARTH_ENABLED
}
exists(/usr/local/include/libfreenect) {
message("Building support for libfreenect")
DEPENDENCIES_PRESENT += libfreenect
INCLUDEPATH += /usr/include/libusb-1.0
# Include libfreenect libraries
LIBS += -lfreenect
DEFINES += QGC_LIBFREENECT_ENABLED
}
# osg/osgEarth dynamic casts might fail without this compiler option.
# see http://osgearth.org/wiki/FAQ for details.
QMAKE_CXXFLAGS += -Wl, -E
}
# Windows (32bit)
......@@ -222,7 +310,13 @@ win32-msvc2008 {
QMAKE_PRE_LINK += cp -f $$BASEDIR/lib/sdl/win32/SDL.dll $$TARGETDIR/debug/. &&
QMAKE_PRE_LINK += cp -f $$BASEDIR/lib/sdl/win32/SDL.dll $$TARGETDIR/release/. &&
QMAKE_PRE_LINK += cp -rf $$BASEDIR/audio $$TARGETDIR/debug/. &&
QMAKE_PRE_LINK += cp -rf $$BASEDIR/audio $$TARGETDIR/release/.
QMAKE_PRE_LINK += cp -rf $$BASEDIR/audio $$TARGETDIR/release/. &&
QMAKE_PRE_LINK += cp -rf $$BASEDIR/models $$TARGETDIR/debug/. &&
QMAKE_PRE_LINK += cp -rf $$BASEDIR/models $$TARGETDIR/release/.
# osg/osgEarth dynamic casts might fail without this compiler option.
# see http://osgearth.org/wiki/FAQ for details.
QMAKE_CXXFLAGS += /Wl /E
}
# Windows (32bit)
......@@ -255,8 +349,14 @@ win32-g++ {
# Copy dependencies
QMAKE_PRE_LINK += cp -f $$BASEDIR/lib/sdl/win32/SDL.dll $$BUILDDIR/debug/. &&
QMAKE_PRE_LINK += cp -f $$BASEDIR/lib/sdl/win32/SDL.dll $$BUILDDIR/release/. &&
QMAKE_PRE_LINK += cp -rf $$BASEDIR/audio $$BUILDDIR/debug/. &&
QMAKE_PRE_LINK += cp -rf $$BASEDIR/audio $$BUILDDIR/release/.
QMAKE_PRE_LINK += cp -rf $$BASEDIR/audio $$TARGETDIR/debug/. &&
QMAKE_PRE_LINK += cp -rf $$BASEDIR/audio $$TARGETDIR/release/.
QMAKE_PRE_LINK += cp -rf $$BASEDIR/models $$TARGETDIR/debug/. &&
QMAKE_PRE_LINK += cp -rf $$BASEDIR/models $$TARGETDIR/release/.
# osg/osgEarth dynamic casts might fail without this compiler option.
# see http://osgearth.org/wiki/FAQ for details.
QMAKE_CXXFLAGS += -Wl, -E
}
# Windows (64bit)
......@@ -291,5 +391,8 @@ win64-g++ {
QMAKE_PRE_LINK += cp -f $$BASEDIR/lib/sdl/win32/SDL.dll $$BUILDDIR/release/. &&
QMAKE_PRE_LINK += cp -rf $$BASEDIR/audio $$BUILDDIR/debug/. &&
QMAKE_PRE_LINK += cp -rf $$BASEDIR/audio $$BUILDDIR/release/.
}
# osg/osgEarth dynamic casts might fail without this compiler option.
# see http://osgearth.org/wiki/FAQ for details.
QMAKE_CXXFLAGS += -Wl, -E
}
......@@ -231,18 +231,35 @@ HEADERS += src/MG.h \
src/ui/RadioCalibration/CurveCalibrator.h \
src/ui/RadioCalibration/AbstractCalibrator.h \
src/comm/QGCMAVLink.h
contains(DEPENDENCIES_PRESENT, osgearth) {
message("Including headers for OSGEARTH")
contains(DEPENDENCIES_PRESENT, osg) {
message("Including headers for OpenSceneGraph")
# Enable only if OpenSceneGraph is available
HEADERS += src/ui/map3D/Q3DWidget.h \
src/ui/map3D/GCManipulator.h \
src/ui/map3D/ImageWindowGeode.h \
src/ui/map3D/QOSGWidget.h \
src/ui/map3D/QMap3D.h \
src/ui/map3D/PixhawkCheetahGeode.h \
src/ui/map3D/Pixhawk3DWidget.h \
src/ui/map3D/Q3DWidgetFactory.h \
src/ui/map3D/GCManipulator.h
src/ui/map3D/Q3DWidgetFactory.h
contains(DEPENDENCIES_PRESENT, osgearth) {
message("Including headers for OSGEARTH")
# Enable only if OpenSceneGraph is available
HEADERS += src/ui/map3D/QMap3D.h
}
}
contains(DEPENDENCIES_PRESENT, libfreenect) {
message("Including headers for libfreenect")
# Enable only if libfreenect is available
HEADERS += src/input/Freenect.h
}
SOURCES += src/main.cc \
src/Core.cc \
src/uas/UASManager.cc \
......@@ -311,19 +328,39 @@ SOURCES += src/main.cc \
src/ui/RadioCalibration/SwitchCalibrator.cc \
src/ui/RadioCalibration/CurveCalibrator.cc \
src/ui/RadioCalibration/AbstractCalibrator.cc \
src/ui/RadioCalibration/RadioCalibrationData.cc # src/ui/WaypointGlobalView.cc \
contains(DEPENDENCIES_PRESENT, osgearth) {
message("Including sources for OSGEARTH")
src/ui/RadioCalibration/RadioCalibrationData.cc
contains(DEPENDENCIES_PRESENT, osg) {
message("Including sources for OpenSceneGraph")
# Enable only if OpenSceneGraph is available
SOURCES += src/ui/map3D/Q3DWidget.cc \
src/ui/map3D/QOSGWidget.cc \
src/ui/map3D/QMap3D.cc \
src/ui/map3D/ImageWindowGeode.cc \
src/ui/map3D/GCManipulator.cc \
src/ui/map3D/QOSGWidget.cc \
src/ui/map3D/PixhawkCheetahGeode.cc \
src/ui/map3D/Pixhawk3DWidget.cc \
src/ui/map3D/Q3DWidgetFactory.cc \
src/ui/map3D/GCManipulator.cc
src/ui/map3D/Q3DWidgetFactory.cc
contains(DEPENDENCIES_PRESENT, osgearth) {
message("Including sources for osgEarth")
# Enable only if OpenSceneGraph is available
SOURCES += src/ui/map3D/QMap3D.cc
}
}
contains(DEPENDENCIES_PRESENT, libfreenect) {
message("Including sources for libfreenect")
# Enable only if libfreenect is available
SOURCES += src/input/Freenect.cc
}
RESOURCES += mavground.qrc
# Include RT-LAB Library
......
#include "Freenect.h"
#include <cmath>
#include <string.h>
#include <QDebug>
Freenect::Freenect()
: context(NULL)
, device(NULL)
, tiltAngle(0)
{
for (int i = 0; i < 2048; ++i)
{
float v = static_cast<float>(i) / 2048.0f;
v = powf(v, 3.0f) * 6.0f;
gammaTable[i] = static_cast<unsigned short>(v * 6.0f * 256.0f);
}
}
Freenect::~Freenect()
{
if (device != NULL)
{
freenect_stop_depth(device);
freenect_stop_rgb(device);
}
freenect_close_device(device);
freenect_shutdown(context);
}
bool
Freenect::init(int userDeviceNumber)
{
if (freenect_init(&context, NULL) < 0)
{
return false;
}
freenect_set_log_level(context, FREENECT_LOG_DEBUG);
if (freenect_num_devices(context) < 1)
{
return false;
}
if (freenect_open_device(context, &device, userDeviceNumber) < 0)
{
return false;
}
freenect_set_user(device, this);
memset(rgb, 0, FREENECT_RGB_SIZE);
memset(depth, 0, FREENECT_DEPTH_SIZE);
// set Kinect parameters
if (freenect_set_tilt_degs(device, tiltAngle) != 0)
{
return false;
}
if (freenect_set_led(device, LED_RED) != 0)
{
return false;
}
if (freenect_set_rgb_format(device, FREENECT_FORMAT_RGB) != 0)
{
return false;
}
if (freenect_set_depth_format(device, FREENECT_FORMAT_11_BIT) != 0)
{
return false;
}
freenect_set_rgb_callback(device, rgbCallback);
freenect_set_depth_callback(device, depthCallback);
if (freenect_start_rgb(device) != 0)
{
return false;
}
if (freenect_start_depth(device) != 0)
{
return false;
}
thread.reset(new FreenectThread(device));
thread->start();
return true;
}
bool
Freenect::process(void)
{
if (freenect_process_events(context) < 0)
{
return false;
}
freenect_get_raw_accel(device, &ax, &ay, &az);
freenect_get_mks_accel(device, &dx, &dy, &dz);
return true;
}
QSharedPointer<QByteArray>
Freenect::getRgbData(void)
{
QMutexLocker locker(&rgbMutex);
return QSharedPointer<QByteArray>(
new QByteArray(rgb, FREENECT_RGB_SIZE));
}
QSharedPointer<QByteArray>
Freenect::getRawDepthData(void)
{
QMutexLocker locker(&depthMutex);
return QSharedPointer<QByteArray>(
new QByteArray(depth, FREENECT_DEPTH_SIZE));
}
QSharedPointer<QByteArray>
Freenect::getDistanceData(void)
{
QMutexLocker locker(&distanceMutex);
return QSharedPointer<QByteArray>(
new QByteArray(reinterpret_cast<char *>(distance),
FREENECT_FRAME_PIX * sizeof(float)));
}
QSharedPointer<QByteArray>
Freenect::getColoredDepthData(void)
{
QMutexLocker locker(&coloredDepthMutex);
return QSharedPointer<QByteArray>(
new QByteArray(coloredDepth, FREENECT_RGB_SIZE));
}
int
Freenect::getTiltAngle(void) const
{
return tiltAngle;
}
void
Freenect::setTiltAngle(int angle)
{
if (angle > 30)
{
angle = 30;
}
if (angle < -30)
{
angle = -30;
}
tiltAngle = angle;
}
Freenect::FreenectThread::FreenectThread(freenect_device* _device)
{
device = _device;
}
void
Freenect::FreenectThread::run(void)
{
Freenect* freenect = static_cast<Freenect *>(freenect_get_user(device));
while (1)
{
freenect->process();
}
}
void
Freenect::rgbCallback(freenect_device* device, freenect_pixel* rgb, uint32_t timestamp)
{
Freenect* freenect = static_cast<Freenect *>(freenect_get_user(device));
QMutexLocker locker(&freenect->rgbMutex);
memcpy(freenect->rgb, rgb, FREENECT_RGB_SIZE);
}
void
Freenect::depthCallback(freenect_device* device, freenect_depth* depth, uint32_t timestamp)
{
Freenect* freenect = static_cast<Freenect *>(freenect_get_user(device));
freenect_depth* data = reinterpret_cast<freenect_depth *>(depth);
QMutexLocker depthLocker(&freenect->depthMutex);
memcpy(freenect->depth, data, FREENECT_DEPTH_SIZE);
QMutexLocker distanceLocker(&freenect->distanceMutex);
for (int i = 0; i < FREENECT_FRAME_PIX; ++i)
{
freenect->distance[i] =
100.f / (-0.00307f * static_cast<float>(data[i]) + 3.33f);
}
QMutexLocker coloredDepthLocker(&freenect->coloredDepthMutex);
unsigned short* src = reinterpret_cast<unsigned short *>(data);
unsigned char* dst = reinterpret_cast<unsigned char *>(freenect->coloredDepth);
for (int i = 0; i < FREENECT_FRAME_PIX; ++i)
{
unsigned short pval = freenect->gammaTable[src[i]];
unsigned short lb = pval & 0xFF;
switch (pval >> 8)
{
case 0:
dst[3 * i] = 255;
dst[3 * i + 1] = 255 - lb;
dst[3 * i + 2] = 255 - lb;
break;
case 1:
dst[3 * i] = 255;
dst[3 * i + 1] = lb;
dst[3 * i + 2] = 0;
break;
case 2:
dst[3 * i] = 255 - lb;
dst[3 * i + 1] = 255;
dst[3 * i + 2] = 0;
break;
case 3:
dst[3 * i] = 0;
dst[3 * i + 1] = 255;
dst[3 * i + 2] = lb;
break;
case 4:
dst[3 * i] = 0;
dst[3 * i + 1] = 255 - lb;
dst[3 * i + 2] = 255;
break;
case 5:
dst[3 * i] = 0;
dst[3 * i + 1] = 0;
dst[3 * i + 2] = 255 - lb;
break;
default:
dst[3 * i] = 0;
dst[3 * i + 1] = 0;
dst[3 * i + 2] = 0;
break;
}
}
}
#ifndef FREENECT_H
#define FREENECT_H
#include <libfreenect.h>
#include <QMutex>
#include <QScopedPointer>
#include <QSharedPointer>
#include <QThread>
class Freenect
{
public:
Freenect();
~Freenect();
bool init(int userDeviceNumber = 0);
bool process(void);
QSharedPointer<QByteArray> getRgbData(void);
QSharedPointer<QByteArray> getRawDepthData(void);
QSharedPointer<QByteArray> getDistanceData(void);
QSharedPointer<QByteArray> getColoredDepthData(void);
int getTiltAngle(void) const;
void setTiltAngle(int angle);
private:
static void rgbCallback(freenect_device* device, freenect_pixel* rgb, uint32_t timestamp);
static void depthCallback(freenect_device* device, freenect_depth* depth, uint32_t timestamp);
freenect_context* context;
freenect_device* device;
class FreenectThread : public QThread
{
public:
explicit FreenectThread(freenect_device* _device);
protected:
virtual void run(void);
freenect_device* device;
};
QScopedPointer<FreenectThread> thread;
// tilt angle of Kinect camera
int tiltAngle;
// rgbd data
char rgb[FREENECT_RGB_SIZE];
QMutex rgbMutex;
char depth[FREENECT_DEPTH_SIZE];
QMutex depthMutex;
float distance[FREENECT_FRAME_PIX];
QMutex distanceMutex;
char coloredDepth[FREENECT_RGB_SIZE];
QMutex coloredDepthMutex;
// accelerometer data
short ax, ay, az;
double dx, dy, dz;
// gamma map
unsigned short gammaTable[2048];
};
#endif // FREENECT_H
......@@ -47,7 +47,7 @@ This file is part of the QGROUNDCONTROL project
#include "GAudioOutput.h"
#ifdef QGC_OSG_ENABLED
#include "QMap3D.h"
#include "Q3DWidgetFactory.h"
#endif
// FIXME Move
......@@ -136,10 +136,13 @@ void MainWindow::buildWidgets()
protocolWidget = new XMLCommProtocolWidget(this);
dataplotWidget = new QGCDataPlot2D(this);
#ifdef QGC_OSG_ENABLED
//_3DWidget = Q3DWidgetFactory::get(QGC_MAP3D_OSGEARTH);
_3DWidget = new QMap3D(this);
_3DWidget = Q3DWidgetFactory::get("PIXHAWK");
#endif
#ifdef QGC_OSGEARTH_ENABLED
_3DMapWidget = Q3DWidgetFactory::get("MAP3D");
#endif
// Dock widgets
controlDockWidget = new QDockWidget(tr("Control"), this);
controlDockWidget->setWidget( new UASControlWidget(this) );
......@@ -232,6 +235,9 @@ void MainWindow::arrangeCenterStack()
if (mapWidget) centerStack->addWidget(mapWidget);
#ifdef QGC_OSG_ENABLED
if (_3DWidget) centerStack->addWidget(_3DWidget);
#endif
#ifdef QGC_OSGEARTH_ENABLED
if (_3DMapWidget) centerStack->addWidget(_3DMapWidget);
#endif
if (hudWidget) centerStack->addWidget(hudWidget);
if (dataplotWidget) centerStack->addWidget(dataplotWidget);
......@@ -373,6 +379,7 @@ void MainWindow::connectActions()
connect(ui.actionEngineerView, SIGNAL(triggered()), this, SLOT(loadEngineerView()));
connect(ui.actionOperatorView, SIGNAL(triggered()), this, SLOT(loadOperatorView()));
connect(ui.action3DView, SIGNAL(triggered()), this, SLOT(load3DView()));
connect(ui.action3DMapView, SIGNAL(triggered()), this, SLOT(load3DMapView()));
connect(ui.actionShow_full_view, SIGNAL(triggered()), this, SLOT(loadAllView()));
connect(ui.actionShow_MAVLink_view, SIGNAL(triggered()), this, SLOT(loadMAVLinkView()));
connect(ui.actionShow_data_analysis_view, SIGNAL(triggered()), this, SLOT(loadDataView()));
......@@ -672,7 +679,7 @@ void MainWindow::loadPixhawkView()
clearView();
// Engineer view, used in EMAV2009
#ifdef QGC_OSG_ENABLED
#ifdef QGC_OSG_ENABLED
// 3D map
if (_3DWidget)
{
......@@ -960,6 +967,60 @@ void MainWindow::loadGlobalOperatorView()
}
void MainWindow::load3DMapView()
{
#ifdef QGC_OSGEARTH_ENABLED
clearView();
// 3D map
if (_3DMapWidget)
{
QStackedWidget *centerStack = dynamic_cast<QStackedWidget*>(centralWidget());
if (centerStack)
{
//map3DWidget->setActive(true);
centerStack->setCurrentWidget(_3DMapWidget);
}
}
// UAS CONTROL
if (controlDockWidget)
{
addDockWidget(Qt::LeftDockWidgetArea, controlDockWidget);
controlDockWidget->show();
}
// UAS LIST
if (listDockWidget)
{
addDockWidget(Qt::BottomDockWidgetArea, listDockWidget);
listDockWidget->show();
}
// WAYPOINT LIST
if (waypointsDockWidget)
{
addDockWidget(Qt::BottomDockWidgetArea, waypointsDockWidget);
waypointsDockWidget->show();
}
// HORIZONTAL SITUATION INDICATOR
if (hsiDockWidget)
{
HSIDisplay* hsi = dynamic_cast<HSIDisplay*>( hsiDockWidget->widget() );
if (hsi)
{
hsi->start();
addDockWidget(Qt::LeftDockWidgetArea, hsiDockWidget);
hsiDockWidget->show();
}
}
#endif
this->show();
}
void MainWindow::load3DView()
{
#ifdef QGC_OSG_ENABLED
......
......@@ -63,10 +63,6 @@ This file is part of the QGROUNDCONTROL project
#include "HSIDisplay.h"
#include "QGCDataPlot2D.h"
#include "QGCRemoteControlView.h"
#ifdef QGC_OSG_ENABLED
//#include "Q3DWidget.h"
#include "QMap3D.h"
#endif
#include "LogCompressor.h"
......@@ -117,6 +113,8 @@ public slots:
void loadOperatorView();
/** @brief Load 3D view */
void load3DView();
/** @brief Load 3D map view */
void load3DMapView();
/** @brief Load view with all widgets */
void loadAllView();
/** @brief Load MAVLink XML generator view */
......@@ -167,7 +165,10 @@ protected:
QPointer<XMLCommProtocolWidget> protocolWidget;
QPointer<QGCDataPlot2D> dataplotWidget;
#ifdef QGC_OSG_ENABLED
QPointer<QMap3D> _3DWidget;
QPointer<QWidget> _3DWidget;
#endif
#ifdef QGC_OSGEARTH_ENABLED
QPointer<QWidget> _3DMapWidget;
#endif
// Dock widgets
QPointer<QDockWidget> controlDockWidget;
......
......@@ -75,6 +75,7 @@
<addaction name="actionEngineerView"/>
<addaction name="actionPilotView"/>
<addaction name="actionOperatorView"/>
<addaction name="action3DMapView"/>
<addaction name="action3DView"/>
<addaction name="actionGlobalOperatorView"/>
<addaction name="separator"/>
......@@ -234,7 +235,7 @@
<normaloff>:/images/categories/preferences-system.svg</normaloff>:/images/categories/preferences-system.svg</iconset>
</property>
<property name="text">
<string>Show 3D view</string>
<string>Show 3D local view</string>
</property>
<property name="toolTip">
<string>Show 3D view</string>
......@@ -318,6 +319,15 @@
<string>Show Global operator view</string>
</property>
</action>
<action name="action3DMapView">
<property name="icon">
<iconset resource="../../mavground.qrc">
<normaloff>:/images/categories/applications-internet.svg</normaloff>:/images/categories/applications-internet.svg</iconset>
</property>
<property name="text">
<string>Show 3D Globe view</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
......
......@@ -254,7 +254,7 @@ GCManipulator::calcMovement()
if (buttonMask == GUIEventAdapter::LEFT_MOUSE_BUTTON)
{
// rotate camera
osg::Vec3 axis;
osg::Vec3d axis;
float angle;
float px0 = _ga_t0->getXnormalized();
......
///*=====================================================================
//
//QGroundControl Open Source Ground Control Station
//
//(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
//
//This file is part of the QGROUNDCONTROL project
//
// QGROUNDCONTROL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// QGROUNDCONTROL is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
//
//======================================================================*/
/**
* @file
* @brief Definition of the class ImageWindowGeode.
*
* @author Lionel Heng <hengli@student.ethz.ch>
*
*/
#include "ImageWindowGeode.h"
ImageWindowGeode::ImageWindowGeode(const QString& caption,
const osg::Vec4& backgroundColor,
osg::ref_ptr<osg::Image>& image)
: border(5)
{
// image
osg::ref_ptr<osg::Geometry> imageGeometry = new osg::Geometry;
imageVertices = new osg::Vec3Array(4);
osg::ref_ptr<osg::Vec2Array> textureCoords = new osg::Vec2Array;
textureCoords->push_back(osg::Vec2(0.0f, 1.0f));
textureCoords->push_back(osg::Vec2(1.0f, 1.0f));
textureCoords->push_back(osg::Vec2(1.0f, 0.0f));
textureCoords->push_back(osg::Vec2(0.0f, 0.0f));
osg::ref_ptr<osg::Vec4Array> imageColors(new osg::Vec4Array);
imageColors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
imageGeometry->setColorArray(imageColors);
imageGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
imageGeometry->setVertexArray(imageVertices);
imageGeometry->setTexCoordArray(0, textureCoords);
imageGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,
0, imageVertices->size()));
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
texture->setDataVariance(osg::Object::DYNAMIC);
texture->setImage(image);
texture->setResizeNonPowerOfTwoHint(false);
imageGeometry->getOrCreateStateSet()->
setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
imageGeometry->setUseDisplayList(false);
// background
osg::ref_ptr<osg::Geometry> backgroundGeometry = new osg::Geometry;
backgroundVertices = new osg::Vec3Array(4);
backgroundGeometry->setVertexArray(backgroundVertices);
backgroundGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,
0, backgroundVertices->size()));
osg::ref_ptr<osg::Vec4Array> backgroundColors(new osg::Vec4Array);
backgroundColors->push_back(backgroundColor);
backgroundGeometry->setColorArray(backgroundColors);
backgroundGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
backgroundGeometry->setUseDisplayList(false);
// caption
text = new osgText::Text;
text->setText(caption.toStdString().c_str());
text->setCharacterSize(11);
text->setFont("images/Vera.ttf");
text->setAxisAlignment(osgText::Text::SCREEN);
text->setColor(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
addDrawable(imageGeometry);
addDrawable(backgroundGeometry);
addDrawable(text);
setAttributes(0, 0, 0, 0);
}
void
ImageWindowGeode::setAttributes(int x, int y, int width, int height)
{
int imageWidth = width - border * 2;
int imageHeight = height - border * 2 - 15;
int imageXPosition = x + border;
int imageYPosition = y + border;
imageVertices->at(0) = osg::Vec3(imageXPosition, imageYPosition, 0);
imageVertices->at(1) = osg::Vec3(imageXPosition + imageWidth, imageYPosition, 0);
imageVertices->at(2) = osg::Vec3(imageXPosition + imageWidth, imageYPosition + imageHeight, 0);
imageVertices->at(3) = osg::Vec3(imageXPosition, imageYPosition + imageHeight, 0);
text->setPosition(osg::Vec3(imageXPosition, imageYPosition + imageHeight + 5, 0));
backgroundVertices->at(0) = osg::Vec3(x, y, -1);
backgroundVertices->at(1) = osg::Vec3(x + width, y, -1);
backgroundVertices->at(2) = osg::Vec3(x + width, y + height, -1);
backgroundVertices->at(3) = osg::Vec3(x, y + height, -1);
}
///*=====================================================================
//
//QGroundControl Open Source Ground Control Station
//
//(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
//
//This file is part of the QGROUNDCONTROL project
//
// QGROUNDCONTROL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// QGROUNDCONTROL is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
//
//======================================================================*/
/**
* @file
* @brief Definition of the class ImageWindowGeode.
*
* @author Lionel Heng <hengli@student.ethz.ch>
*
*/
#ifndef IMAGEWINDOWGEODE_H
#define IMAGEWINDOWGEODE_H
#include <osg/Geode>
#include <osg/Geometry>
#include <osgText/Text>
#include <QString>
class ImageWindowGeode : public osg::Geode
{
public:
ImageWindowGeode(const QString& caption, const osg::Vec4& backgroundColor,
osg::ref_ptr<osg::Image>& image);
void setAttributes(int x, int y, int width, int height);
private:
int border;
osg::ref_ptr<osg::Vec3Array> imageVertices;
osg::ref_ptr<osg::Vec3Array> backgroundVertices;
osg::ref_ptr<osgText::Text> text;
};
#endif // IMAGEWINDOWGEODE_H
This diff is collapsed.
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Definition of the class Imagery.
*
* @author Lionel Heng <hengli@student.ethz.ch>
*
*/
#ifndef IMAGERY_H
#define IMAGERY_H
#include <QScopedPointer>
#include <QString>
#include "TextureCache.h"
class Imagery
{
public:
enum ImageryType
{
GOOGLE_MAP = 0,
GOOGLE_SATELLITE = 1,
SWISSTOPO_SATELLITE = 2,
SWISSTOPO_SATELLITE_3D = 3
};
Imagery();
void setImageryType(ImageryType type);
void setOffset(double xOffset, double yOffset);
void prefetch2D(double windowWidth, double windowHeight,
double zoom, double xOrigin, double yOrigin,
double viewXOffset, double viewYOffset,
const QString& utmZone);
void draw2D(double windowWidth, double windowHeight,
double zoom, double xOrigin, double yOrigin,
double viewXOffset, double viewYOffset,
const QString& utmZone);
void prefetch3D(double radius, double tileResolution,
double xOrigin, double yOrigin,
double viewXOffset, double viewYOffset,
const QString& utmZone, bool useHeightModel);
void draw3D(double radius, double tileResolution,
double xOrigin, double yOrigin,
double viewXOffset, double viewYOffset,
const QString& utmZone, bool useHeightModel);
bool update(void);
private:
void imageBounds(int tileX, int tileY, double tileResolution,
double& x1, double& y1, double& x2, double& y2,
double& x3, double& y3, double& x4, double& y4) const;
void tileBounds(double tileResolution,
double minUtmX, double minUtmY,
double maxUtmX, double maxUtmY, const QString& utmZone,
int& minTileX, int& minTileY,
int& maxTileX, int& maxTileY,
int& zoomLevel) const;
double tileXToLongitude(int tileX, int numTiles) const;
double tileYToLatitude(int tileY, int numTiles) const;
int longitudeToTileX(double longitude, int numTiles) const;
int latitudeToTileY(double latitude, int numTiles) const;
void UTMtoTile(double northing, double easting, const QString& utmZone,
double tileResolution, int& tileX, int& tileY,
int& zoomLevel) const;
QChar UTMLetterDesignator(double latitude) const;
void LLtoUTM(double latitude, double longitude,
double& utmNorthing, double& utmEasting,
QString& utmZone) const;
void UTMtoLL(double utmNorthing, double utmEasting, const QString& utmZone,
double& latitude, double& longitude) const;
QString getTileLocation(int tileX, int tileY, int zoomLevel,
double tileResolution) const;
QScopedPointer<TextureCache> textureCache;
ImageryType currentImageryType;
double xOffset;
double yOffset;
};
#endif // IMAGERY_H
......@@ -34,6 +34,8 @@
#include <sstream>
#include <osg/Geode>
#include <osg/Image>
#include <osgDB/ReadFile>
#include <osg/LineWidth>
#include <osg/ShapeDrawable>
......@@ -49,6 +51,8 @@ Pixhawk3DWidget::Pixhawk3DWidget(QWidget* parent)
, displayTrail(false)
, displayTarget(false)
, displayWaypoints(true)
, displayRGBD2D(false)
, displayRGBD3D(false)
, followCamera(true)
, lastRobotX(0.0f)
, lastRobotY(0.0f)
......@@ -58,7 +62,8 @@ Pixhawk3DWidget::Pixhawk3DWidget(QWidget* parent)
init(15.0f);
// generate Pixhawk Cheetah model
egocentricMap->addChild(PixhawkCheetahGeode::instance());
vehicleModel = PixhawkCheetahGeode::instance();
egocentricMap->addChild(vehicleModel);
// generate grid model
gridNode = createGrid();
......@@ -68,9 +73,11 @@ Pixhawk3DWidget::Pixhawk3DWidget(QWidget* parent)
trailNode = createTrail();
rollingMap->addChild(trailNode);
#ifdef QGC_OSGEARTH_ENABLED
// generate map model
mapNode = createMap();
root->addChild(mapNode);
#endif
// generate target model
allocentricMap->addChild(createTarget());
......@@ -79,8 +86,20 @@ Pixhawk3DWidget::Pixhawk3DWidget(QWidget* parent)
waypointsNode = createWaypoints();
rollingMap->addChild(waypointsNode);
#ifdef QGC_LIBFREENECT_ENABLED
freenect.reset(new Freenect());
freenect->init();
#endif
// generate RGBD model
rgbd3DNode = createRGBD3D();
egocentricMap->addChild(rgbd3DNode);
setupHUD();
// find available vehicle models in models folder
vehicleModels = findVehicleModels();
buildLayout();
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
......@@ -92,59 +111,6 @@ Pixhawk3DWidget::~Pixhawk3DWidget()
}
void
Pixhawk3DWidget::buildLayout(void)
{
QCheckBox* gridCheckBox = new QCheckBox(this);
gridCheckBox->setText("Grid");
gridCheckBox->setChecked(displayGrid);
QCheckBox* trailCheckBox = new QCheckBox(this);
trailCheckBox->setText("Trail");
trailCheckBox->setChecked(displayTrail);
QCheckBox* waypointsCheckBox = new QCheckBox(this);
waypointsCheckBox->setText("Waypoints");
waypointsCheckBox->setChecked(displayWaypoints);
targetButton = new QPushButton(this);
targetButton->setCheckable(true);
targetButton->setChecked(false);
targetButton->setIcon(QIcon(QString::fromUtf8(":/images/status/weather-clear.svg")));
QPushButton* recenterButton = new QPushButton(this);
recenterButton->setText("Recenter Camera");
QCheckBox* followCameraCheckBox = new QCheckBox(this);
followCameraCheckBox->setText("Follow Camera");
followCameraCheckBox->setChecked(followCamera);
QGridLayout* layout = new QGridLayout(this);
layout->setMargin(0);
layout->setSpacing(2);
layout->addWidget(gridCheckBox, 1, 0);
layout->addWidget(trailCheckBox, 1, 1);
layout->addWidget(waypointsCheckBox, 1, 2);
layout->addItem(new QSpacerItem(20, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 1, 3);
layout->addWidget(targetButton, 1, 4);
layout->addItem(new QSpacerItem(20, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 1, 5);
layout->addWidget(recenterButton, 1, 6);
layout->addWidget(followCameraCheckBox, 1, 7);
layout->setRowStretch(0, 100);
layout->setRowStretch(1, 1);
setLayout(layout);
connect(gridCheckBox, SIGNAL(stateChanged(int)),
this, SLOT(showGrid(int)));
connect(trailCheckBox, SIGNAL(stateChanged(int)),
this, SLOT(showTrail(int)));
connect(waypointsCheckBox, SIGNAL(stateChanged(int)),
this, SLOT(showWaypoints(int)));
connect(recenterButton, SIGNAL(clicked()), this, SLOT(recenter()));
connect(followCameraCheckBox, SIGNAL(stateChanged(int)),
this, SLOT(toggleFollowCamera(int)));
}
/**
*
* @param uas the UAS/MAV to monitor/display with the HUD
......@@ -204,6 +170,14 @@ Pixhawk3DWidget::showWaypoints(int state)
}
}
void
Pixhawk3DWidget::selectVehicleModel(int index)
{
egocentricMap->removeChild(vehicleModel);
vehicleModel = vehicleModels.at(index);
egocentricMap->addChild(vehicleModel);
}
void
Pixhawk3DWidget::recenter(void)
{
......@@ -230,6 +204,123 @@ Pixhawk3DWidget::toggleFollowCamera(int32_t state)
followCamera = false;
}
}
#include <osgDB/WriteFile>
QVector< osg::ref_ptr<osg::Node> >
Pixhawk3DWidget::findVehicleModels(void)
{
QDir directory("models");
QStringList files = directory.entryList(QStringList("*.osg"), QDir::Files);
QVector< osg::ref_ptr<osg::Node> > nodes;
// add Pixhawk Bravo model
nodes.push_back(PixhawkCheetahGeode::instance());
// add all other models in folder
for (int i = 0; i < files.size(); ++i)
{
osg::ref_ptr<osg::Node> node =
osgDB::readNodeFile(directory.absoluteFilePath(files[i]).toStdString().c_str());
if (node)
{
nodes.push_back(node);
}
else
{
printf(QString("ERROR: Could not load file " + directory.absoluteFilePath(files[i]) + "\n").toStdString().c_str());
}
}
// QStringList dirs = directory.entryList(QDir::Dirs);
// // Add models in subfolders
// for (int i = 0; i < dirs.size(); ++i)
// {
// // Handling the current directory
// QStringList currFiles = QDir(dirs[i]).entryList(QStringList("*.ac"), QDir::Files);
// // Load the file
// osg::ref_ptr<osg::Node> node =
// osgDB::readNodeFile(directory.absoluteFilePath(currFiles.first()).toStdString().c_str());
// if (node)
// {
// nodes.push_back(node);
// }
// else
// {
// printf(QString("ERROR: Could not load file " + directory.absoluteFilePath(files[i]) + "\n").toStdString().c_str());
// }
// }
return nodes;
}
void
Pixhawk3DWidget::buildLayout(void)
{
QCheckBox* gridCheckBox = new QCheckBox(this);
gridCheckBox->setText("Grid");
gridCheckBox->setChecked(displayGrid);
QCheckBox* trailCheckBox = new QCheckBox(this);
trailCheckBox->setText("Trail");
trailCheckBox->setChecked(displayTrail);
QCheckBox* waypointsCheckBox = new QCheckBox(this);
waypointsCheckBox->setText("Waypoints");
waypointsCheckBox->setChecked(displayWaypoints);
QLabel* modelLabel = new QLabel("Vehicle Model", this);
QComboBox* modelComboBox = new QComboBox(this);
for (int i = 0; i < vehicleModels.size(); ++i)
{
modelComboBox->addItem(vehicleModels[i]->getName().c_str());
}
targetButton = new QPushButton(this);
targetButton->setCheckable(true);
targetButton->setChecked(false);
targetButton->setIcon(QIcon(QString::fromUtf8(":/images/status/weather-clear.svg")));
QPushButton* recenterButton = new QPushButton(this);
recenterButton->setText("Recenter Camera");
QCheckBox* followCameraCheckBox = new QCheckBox(this);
followCameraCheckBox->setText("Follow Camera");
followCameraCheckBox->setChecked(followCamera);
QGridLayout* layout = new QGridLayout(this);
layout->setMargin(0);
layout->setSpacing(2);
layout->addWidget(gridCheckBox, 1, 0);
layout->addWidget(trailCheckBox, 1, 1);
layout->addWidget(waypointsCheckBox, 1, 2);
layout->addItem(new QSpacerItem(10, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 1, 3);
layout->addWidget(modelLabel, 1, 4);
layout->addWidget(modelComboBox, 1, 5);
layout->addWidget(targetButton, 1, 6);
layout->addItem(new QSpacerItem(10, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 1, 7);
layout->addWidget(recenterButton, 1, 8);
layout->addWidget(followCameraCheckBox, 1, 9);
layout->setRowStretch(0, 100);
layout->setRowStretch(1, 1);
setLayout(layout);
connect(gridCheckBox, SIGNAL(stateChanged(int)),
this, SLOT(showGrid(int)));
connect(trailCheckBox, SIGNAL(stateChanged(int)),
this, SLOT(showTrail(int)));
connect(waypointsCheckBox, SIGNAL(stateChanged(int)),
this, SLOT(showWaypoints(int)));
connect(modelComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(selectVehicleModel(int)));
connect(recenterButton, SIGNAL(clicked()), this, SLOT(recenter()));
connect(followCameraCheckBox, SIGNAL(stateChanged(int)),
this, SLOT(toggleFollowCamera(int)));
}
void
Pixhawk3DWidget::display(void)
......@@ -271,22 +362,47 @@ Pixhawk3DWidget::display(void)
robotPitch, osg::Vec3f(1.0f, 0.0f, 0.0f),
robotRoll, osg::Vec3f(0.0f, 1.0f, 0.0f)));
updateHUD(robotX, robotY, robotZ, robotRoll, robotPitch, robotYaw);
updateTrail(robotX, robotY, robotZ);
updateTarget();
updateWaypoints();
#ifdef QGC_LIBFREENECT_ENABLED
updateRGBD();
#endif
updateHUD(robotX, robotY, robotZ, robotRoll, robotPitch, robotYaw);
// set node visibility
rollingMap->setChildValue(gridNode, displayGrid);
rollingMap->setChildValue(trailNode, displayTrail);
rollingMap->setChildValue(targetNode, displayTarget);
rollingMap->setChildValue(waypointsNode, displayWaypoints);
egocentricMap->setChildValue(rgbd3DNode, displayRGBD3D);
hudGroup->setChildValue(rgb2DGeode, displayRGBD2D);
hudGroup->setChildValue(depth2DGeode, displayRGBD2D);
lastRobotX = robotX;
lastRobotY = robotY;
lastRobotZ = robotZ;
}
void
Pixhawk3DWidget::keyPressEvent(QKeyEvent* event)
{
if (!event->text().isEmpty())
{
switch (*(event->text().toAscii().data()))
{
case '1':
displayRGBD2D = !displayRGBD2D;
break;
case '2':
displayRGBD3D = !displayRGBD3D;
break;
}
}
Q3DWidget::keyPressEvent(event);
}
void
Pixhawk3DWidget::mousePressEvent(QMouseEvent* event)
{
......@@ -393,6 +509,7 @@ Pixhawk3DWidget::createTrail(void)
return geode;
}
#ifdef QGC_OSGEARTH_ENABLED
osg::ref_ptr<osgEarth::MapNode>
Pixhawk3DWidget::createMap(void)
{
......@@ -401,6 +518,7 @@ Pixhawk3DWidget::createMap(void)
return node;
}
#endif
osg::ref_ptr<osg::Node>
Pixhawk3DWidget::createTarget(void)
......@@ -421,72 +539,111 @@ Pixhawk3DWidget::createWaypoints(void)
return group;
}
osg::ref_ptr<osg::Geode>
Pixhawk3DWidget::createRGBD3D(void)
{
int frameSize = 640 * 480;
osg::ref_ptr<osg::Geode> geode(new osg::Geode);
osg::ref_ptr<osg::Geometry> geometry(new osg::Geometry);
osg::ref_ptr<osg::Vec3Array> vertices(new osg::Vec3Array(frameSize));
geometry->setVertexArray(vertices);
osg::ref_ptr<osg::Vec4Array> colors(new osg::Vec4Array(frameSize));
geometry->setColorArray(colors);
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
geometry->setUseDisplayList(false);
geode->addDrawable(geometry);
return geode;
}
void
Pixhawk3DWidget::setupHUD(void)
{
osg::ref_ptr<osg::Vec3Array> hudBackgroundVertices(new osg::Vec3Array);
hudBackgroundVertices->push_back(osg::Vec3(0, height(), -1));
hudBackgroundVertices->push_back(osg::Vec3(width(), height(), -1));
hudBackgroundVertices->push_back(osg::Vec3(width(), height() - 30, -1));
hudBackgroundVertices->push_back(osg::Vec3(0, height() - 30, -1));
hudBackgroundVertices->push_back(osg::Vec3(0, 0, -1));
hudBackgroundVertices->push_back(osg::Vec3(width(), 0, -1));
hudBackgroundVertices->push_back(osg::Vec3(width(), 25, -1));
hudBackgroundVertices->push_back(osg::Vec3(0, 25, -1));
osg::ref_ptr<osg::DrawElementsUInt> hudTopBackgroundIndices(
new osg::DrawElementsUInt(osg::PrimitiveSet::POLYGON, 0));
hudTopBackgroundIndices->push_back(0);
hudTopBackgroundIndices->push_back(1);
hudTopBackgroundIndices->push_back(2);
hudTopBackgroundIndices->push_back(3);
osg::ref_ptr<osg::DrawElementsUInt> hudBottomBackgroundIndices(
new osg::DrawElementsUInt(osg::PrimitiveSet::POLYGON, 0));
hudBottomBackgroundIndices->push_back(4);
hudBottomBackgroundIndices->push_back(5);
hudBottomBackgroundIndices->push_back(6);
hudBottomBackgroundIndices->push_back(7);
osg::ref_ptr<osg::Vec4Array> hudColors(new osg::Vec4Array);
hudColors->push_back(osg::Vec4(0.0f, 0.0f, 0.0f, 0.2f));
hudBackgroundGeometry = new osg::Geometry;
hudBackgroundGeometry->addPrimitiveSet(hudTopBackgroundIndices);
hudBackgroundGeometry->addPrimitiveSet(hudBottomBackgroundIndices);
hudBackgroundGeometry->setVertexArray(hudBackgroundVertices);
hudBackgroundGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,
0, 4));
hudBackgroundGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,
4, 4));
hudBackgroundGeometry->setColorArray(hudColors);
hudBackgroundGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
hudGeode->addDrawable(hudBackgroundGeometry);
hudBackgroundGeometry->setUseDisplayList(false);
statusText = new osgText::Text;
statusText->setCharacterSize(11);
statusText->setFont("images/Vera.ttf");
statusText->setAxisAlignment(osgText::Text::SCREEN);
statusText->setPosition(osg::Vec3(10, height() - 10, -1.5));
statusText->setColor(osg::Vec4(255, 255, 255, 1));
hudGeode->addDrawable(statusText);
resizeHUD();
osg::ref_ptr<osg::Geode> statusGeode = new osg::Geode;
statusGeode->addDrawable(hudBackgroundGeometry);
statusGeode->addDrawable(statusText);
hudGroup->addChild(statusGeode);
rgbImage = new osg::Image;
rgb2DGeode = new ImageWindowGeode("RGB Image",
osg::Vec4(0.0f, 0.0f, 0.1f, 1.0f),
rgbImage);
hudGroup->addChild(rgb2DGeode);
depthImage = new osg::Image;
depth2DGeode = new ImageWindowGeode("Depth Image",
osg::Vec4(0.0f, 0.0f, 0.1f, 1.0f),
depthImage);
hudGroup->addChild(depth2DGeode);
}
void
Pixhawk3DWidget::updateHUD(float robotX, float robotY, float robotZ,
float robotRoll, float robotPitch, float robotYaw)
Pixhawk3DWidget::resizeHUD(void)
{
osg::ref_ptr<osg::Vec3Array> hudBackgroundVertices(new osg::Vec3Array);
hudBackgroundVertices->push_back(osg::Vec3(0, height(), -1));
hudBackgroundVertices->push_back(osg::Vec3(width(), height(), -1));
hudBackgroundVertices->push_back(osg::Vec3(width(), height() - 30, -1));
hudBackgroundVertices->push_back(osg::Vec3(0, height() - 30, -1));
hudBackgroundVertices->push_back(osg::Vec3(0, 0, -1));
hudBackgroundVertices->push_back(osg::Vec3(width(), 0, -1));
hudBackgroundVertices->push_back(osg::Vec3(width(), 25, -1));
hudBackgroundVertices->push_back(osg::Vec3(0, 25, -1));
hudBackgroundGeometry->setVertexArray(hudBackgroundVertices);
int topHUDHeight = 30;
int bottomHUDHeight = 25;
osg::Vec3Array* vertices = static_cast<osg::Vec3Array*>(hudBackgroundGeometry->getVertexArray());
if (vertices == NULL || vertices->size() != 8)
{
osg::ref_ptr<osg::Vec3Array> newVertices = new osg::Vec3Array(8);
hudBackgroundGeometry->setVertexArray(newVertices);
vertices = static_cast<osg::Vec3Array*>(hudBackgroundGeometry->getVertexArray());
}
(*vertices)[0] = osg::Vec3(0, height(), -1);
(*vertices)[1] = osg::Vec3(width(), height(), -1);
(*vertices)[2] = osg::Vec3(width(), height() - topHUDHeight, -1);
(*vertices)[3] = osg::Vec3(0, height() - topHUDHeight, -1);
(*vertices)[4] = osg::Vec3(0, 0, -1);
(*vertices)[5] = osg::Vec3(width(), 0, -1);
(*vertices)[6] = osg::Vec3(width(), bottomHUDHeight, -1);
(*vertices)[7] = osg::Vec3(0, bottomHUDHeight, -1);
statusText->setPosition(osg::Vec3(10, height() - 20, -1.5));
if (rgb2DGeode.valid() && depth2DGeode.valid())
{
int windowWidth = (width() - 20) / 2;
int windowHeight = 3 * windowWidth / 4;
rgb2DGeode->setAttributes(10, (height() - windowHeight) / 2,
windowWidth, windowHeight);
depth2DGeode->setAttributes(width() / 2, (height() - windowHeight) / 2,
windowWidth, windowHeight);
}
}
void
Pixhawk3DWidget::updateHUD(float robotX, float robotY, float robotZ,
float robotRoll, float robotPitch, float robotYaw)
{
resizeHUD();
std::pair<double,double> cursorPosition =
getGlobalCursorPosition(getMouseX(), getMouseY(), -robotZ);
......@@ -502,6 +659,21 @@ Pixhawk3DWidget::updateHUD(float robotX, float robotY, float robotZ,
" Cursor [" << cursorPosition.first <<
" " << cursorPosition.second << "]";
statusText->setText(oss.str());
if (!rgb.isNull())
{
rgbImage->setImage(640, 480, 1,
GL_RGB, GL_RGB, GL_UNSIGNED_BYTE,
reinterpret_cast<unsigned char *>(rgb->data()),
osg::Image::NO_DELETE);
rgbImage->dirty();
depthImage->setImage(640, 480, 1,
GL_RGB, GL_RGB, GL_UNSIGNED_BYTE,
reinterpret_cast<unsigned char *>(coloredDepth->data()),
osg::Image::NO_DELETE);
depthImage->dirty();
}
}
void
......@@ -637,6 +809,14 @@ Pixhawk3DWidget::updateWaypoints(void)
}
}
#ifdef QGC_LIBFREENECT_ENABLED
void
Pixhawk3DWidget::updateRGBD(void)
{
rgb = freenect->getRgbData();
coloredDepth = freenect->getColoredDepthData();
}
#endif
void
Pixhawk3DWidget::markTarget(void)
......
......@@ -33,7 +33,15 @@
#define PIXHAWK3DWIDGET_H
#include <osgText/Text>
#ifdef QGC_OSGEARTH_ENABLED
#include <osgEarth/MapNode>
#endif
#include "ImageWindowGeode.h"
#ifdef QGC_LIBFREENECT_ENABLED
#include "Freenect.h"
#endif
#include "Q3DWidget.h"
......@@ -50,10 +58,6 @@ public:
explicit Pixhawk3DWidget(QWidget* parent = 0);
~Pixhawk3DWidget();
void buildLayout(void);
double getTime(void) const;
public slots:
void setActiveUAS(UASInterface* uas);
......@@ -61,11 +65,15 @@ private slots:
void showGrid(int state);
void showTrail(int state);
void showWaypoints(int state);
void selectVehicleModel(int index);
void recenter(void);
void toggleFollowCamera(int state);
protected:
QVector< osg::ref_ptr<osg::Node> > findVehicleModels(void);
void buildLayout(void);
virtual void display(void);
virtual void keyPressEvent(QKeyEvent* event);
virtual void mousePressEvent(QMouseEvent* event);
UASInterface* uas;
......@@ -73,17 +81,26 @@ protected:
private:
osg::ref_ptr<osg::Geode> createGrid(void);
osg::ref_ptr<osg::Geode> createTrail(void);
#ifdef QGC_OSGEARTH_ENABLED
osg::ref_ptr<osgEarth::MapNode> createMap(void);
#endif
osg::ref_ptr<osg::Node> createTarget(void);
osg::ref_ptr<osg::Group> createWaypoints(void);
osg::ref_ptr<osg::Geode> createRGBD3D(void);
void setupHUD(void);
void resizeHUD(void);
void updateHUD(float robotX, float robotY, float robotZ,
float robotRoll, float robotPitch, float robotYaw);
void updateTrail(float robotX, float robotY, float robotZ);
void updateTarget(void);
void updateWaypoints(void);
#ifdef QGC_LIBFREENECT_ENABLED
void updateRGBD(void);
#endif
void markTarget(void);
......@@ -91,22 +108,39 @@ private:
bool displayTrail;
bool displayTarget;
bool displayWaypoints;
bool displayRGBD2D;
bool displayRGBD3D;
bool followCamera;
osg::ref_ptr<osg::Vec3Array> trailVertices;
QVarLengthArray<osg::Vec3, 10000> trail;
osg::ref_ptr<osg::Node> vehicleModel;
osg::ref_ptr<osg::Geometry> hudBackgroundGeometry;
osg::ref_ptr<osgText::Text> statusText;
osg::ref_ptr<ImageWindowGeode> rgb2DGeode;
osg::ref_ptr<ImageWindowGeode> depth2DGeode;
osg::ref_ptr<osg::Image> rgbImage;
osg::ref_ptr<osg::Image> depthImage;
osg::ref_ptr<osg::Geode> gridNode;
osg::ref_ptr<osg::Geode> trailNode;
osg::ref_ptr<osg::Geometry> trailGeometry;
osg::ref_ptr<osg::DrawArrays> trailDrawArrays;
#ifdef QGC_OSGEARTH_ENABLED
osg::ref_ptr<osgEarth::MapNode> mapNode;
#endif
osg::ref_ptr<osg::Geode> targetNode;
osg::ref_ptr<osg::PositionAttitudeTransform> targetPosition;
osg::ref_ptr<osg::Group> waypointsNode;
osg::ref_ptr<osg::Geode> rgbd3DNode;
#ifdef QGC_LIBFREENECT_ENABLED
QScopedPointer<Freenect> freenect;
#endif
QSharedPointer<QByteArray> rgb;
QSharedPointer<QByteArray> coloredDepth;
QVector< osg::ref_ptr<osg::Node> > vehicleModels;
QPushButton* targetButton;
......
......@@ -59358,6 +59358,7 @@ osg::ref_ptr<osg::Geode>
PixhawkCheetahGeode::create(float red, float green, float blue)
{
osg::ref_ptr<osg::Geode> geode(new osg::Geode());
geode->setName("Pixhawk Bravo");
osg::ref_ptr<osg::Geometry> geometry(new osg::Geometry());
geode->addDrawable(geometry.get());
 
......@@ -34,10 +34,7 @@ This file is part of the QGROUNDCONTROL project
#include <osg/Geometry>
#include <osg/LineWidth>
#include <osg/MatrixTransform>
static const float KEY_ROTATE_AMOUNT = 5.0f;
static const float KEY_MOVE_AMOUNT = 10.0f;
static const float KEY_ZOOM_AMOUNT = 5.0f;
#include <Carbon/Carbon.h>
Q3DWidget::Q3DWidget(QWidget* parent)
: QGLWidget(parent)
......@@ -47,7 +44,7 @@ Q3DWidget::Q3DWidget(QWidget* parent)
, egocentricMap(new osg::Switch())
, robotPosition(new osg::PositionAttitudeTransform())
, robotAttitude(new osg::PositionAttitudeTransform())
, hudGeode(new osg::Geode())
, hudGroup(new osg::Switch())
, hudProjectionMatrix(new osg::Projection)
{
// set initial camera parameters
......@@ -94,7 +91,7 @@ Q3DWidget::init(float fps)
egocentricMap->addChild(createRobot());
// set up camera control
cameraManipulator = new GCManipulator;
cameraManipulator = new GCManipulator();
setCameraManipulator(cameraManipulator);
cameraManipulator->setMinZoomRange(cameraParams.minZoomRange);
cameraManipulator->setDistance(cameraParams.minZoomRange * 2.0);
......@@ -159,11 +156,12 @@ Q3DWidget::createHUD(void)
hudModelViewMatrix->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
hudProjectionMatrix->addChild(hudModelViewMatrix);
hudModelViewMatrix->addChild(hudGeode);
hudModelViewMatrix->addChild(hudGroup);
osg::ref_ptr<osg::StateSet> hudStateSet(new osg::StateSet);
hudGeode->setStateSet(hudStateSet);
hudGroup->setStateSet(hudStateSet);
hudStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
hudStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
hudStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
hudStateSet->setRenderBinDetails(11, "RenderBin");
......
......@@ -249,7 +249,7 @@ protected:
osg::ref_ptr<osg::PositionAttitudeTransform> robotPosition;
osg::ref_ptr<osg::PositionAttitudeTransform> robotAttitude;
osg::ref_ptr<osg::Geode> hudGeode; /**< A geode which contains renderable HUD objects. */
osg::ref_ptr<osg::Switch> hudGroup; /**< A group which contains renderable HUD objects. */
osg::ref_ptr<osg::Projection> hudProjectionMatrix; /**< An orthographic projection matrix for HUD display. */
osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> osgGW; /**< A class which manages OSG graphics windows and events. */
......
......@@ -32,16 +32,25 @@ This file is part of the QGROUNDCONTROL project
#include "Q3DWidgetFactory.h"
#include "Pixhawk3DWidget.h"
#ifdef QGC_OSGEARTH_ENABLED
#include "QMap3D.h"
#endif
QPointer<Q3DWidget>
QPointer<QWidget>
Q3DWidgetFactory::get(const std::string& type)
{
if (type == "PIXHAWK")
{
return QPointer<Q3DWidget>(new Pixhawk3DWidget);
return QPointer<QWidget>(new Pixhawk3DWidget());
}
#ifdef QGC_OSGEARTH_ENABLED
else if (type == "MAP3D")
{
return QPointer<QWidget>(new QMap3D());
}
#endif
else
{
return QPointer<Q3DWidget>(new Q3DWidget);
return QPointer<QWidget>(new Q3DWidget());
}
}
......@@ -50,7 +50,7 @@ public:
* @return A smart pointer to the Q3DWidget instance.
*/
static QPointer<Q3DWidget> get(const std::string& type);
static QPointer<QWidget> get(const std::string& type);
};
#endif // Q3DWIDGETFACTORY_H
Supports Markdown
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