Browse Source

Added Google Earth support for Mac platform

QGC4.4
pixhawk 14 years ago
parent
commit
e4ea6b31dc
  1. 202
      images/earth.html
  2. 4
      lib/QMapControl/src/mapnetwork.cpp
  3. BIN
      models/ascent-park-glider.skp
  4. BIN
      models/multiplex-easyglider.skp
  5. BIN
      models/multiplex-twinstar.skp
  6. BIN
      models/walkera-4g6.skp
  7. 4
      qgroundcontrol.pri
  8. 9
      qgroundcontrol.pro
  9. 4
      src/uas/UAS.cc
  10. 6
      src/uas/UAS.h
  11. 4
      src/uas/UASInterface.h
  12. 87
      src/ui/map3D/QGCGoogleEarthView.cc
  13. 39
      src/ui/map3D/QGCGoogleEarthView.h
  14. 21
      src/ui/map3D/QGCGoogleEarthViewWin.ui
  15. 12
      src/ui/map3D/QGCWebPage.cc
  16. 21
      src/ui/map3D/QGCWebPage.h

202
images/earth.html

@ -1,34 +1,101 @@ @@ -1,34 +1,101 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
<html>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<head>
<!--
Copyright 2008 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- QGroundControl -->
<title>QGroundControl Google Earth View</title>
<!-- *** Replace the key below below with your own API key, available at http://code.google.com/apis/maps/signup.html *** -->
<script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAAwbkbZLyhsmTCWXbTcjbgbRSzHs7K5SvaUdm8ua-Xxy_-2dYwMxQMhnagaawTo7L1FE1-amhuQxIlXw"></script>
<script type="text/javascript">
google.load("earth", "1");
google.load("earth", "1", { 'language': 'en'});
var ge = null;
var initialized = false;
var aircraft = new Array();
var currAircraft = 220;
var followAircraft = false;
var currLat = 47.3769;
var currLon = 8.549444;
var currAlt = 470;
var homeLat = 0;
var homeLon = 0;
var homeAlt = 0;
var homeViewRange = 500;
var homeLocation = null;
var homeGroundLevel = 0;
var currViewRange = 3.0; ///<< The current viewing range from this position (in meters)
var currTilt = 40.0; ///<< The tilt angle (in degrees)
var currFollowTilt = 40.0;
var currView = null;
var planeOrient;
var planeLoc;
// Aircraft class
function isInitialized()
{
return initialized;
}
function init() {
google.earth.createInstance("map3d", initCallback, failureCallback);
google.earth.createInstance("map3d", initCallback, failureCallback);
}
function setGCSHome(lat, lon, alt)
{
homeLat = lat;
homeLon = lon;
homeAlt = alt;
var placemark = ge.createPlacemark('');
var icon = ge.createIcon('');
icon.setHref('http://google-maps-icons.googlecode.com/files/blackH.png');
var style = ge.createStyle('');
style.getIconStyle().setIcon(icon);
//style.getIconStyle().setScale(0.5);
placemark.setStyleSelector(style);
// Set the placemark's location.
homeLocation = ge.createPoint('');
homeLocation.setLatitude(lat);
homeLocation.setLongitude(lon);
homeLocation.setAltitude(alt);
placemark.setGeometry(homeLocation);
// Add the placemark to Earth.
ge.getFeatures().appendChild(placemark);
homeGroundLevel = ge.getGlobe().getGroundAltitude(lat,lon);
if (homeGroundLevel == 0)
{
homeGroundLevel = alt;
}
goHome();
}
function initCallback(object) {
function initCallback(object)
{
ge = object;
ge.getWindow().setVisibility(true);
ge.getOptions().setStatusBarVisibility(true);
@ -40,11 +107,104 @@ function initCallback(object) { @@ -40,11 +107,104 @@ function initCallback(object) {
ge.getLayerRoot().enableLayerById(ge.LAYER_BUILDINGS, true);
ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true);
ge.getLayerRoot().enableLayerById(ge.LAYER_TREES, true);
// Now after the Google Earth initialization, initialize the GCS view
setGCSHome(currLat, currLon, currAlt);
// Create the first aircraft model
// Load 3D model
var planePlacemark = ge.createPlacemark('');
planePlacemark.setName('aircraft');
planeModel = ge.createModel('');
ge.getFeatures().appendChild(planePlacemark);
planeLoc = ge.createLocation('');
planeModel.setLocation(planeLoc);
planeLink = ge.createLink('');
planeOrient = ge.createOrientation('');
planeModel.setOrientation(planeOrient);
planeLink.setHref('http://qgroundcontrol.org/_media/users/models/multiplex-twinstar.dae');
planeModel.setLink(planeLink);
planeModel.setAltitudeMode (ge.ALTITUDE_ABSOLUTE);
planeLoc.setLatitude(currLat);
planeLoc.setLongitude(currLon);
planeLoc.setAltitude(currAlt);
planePlacemark.setGeometry(planeModel);
setAircraftPositionAttitude(220, 47.3772, currLon, currAlt+50, 20, 15, 50);
enableFollowing(true);
updateFollowAircraft();
initialized = true;
}
function setAircraftPositionAttitude(id, lat, lon, alt, roll, pitch, yaw)
{
if (id == currAircraft)
{
currLat = lat;
currLon = lon;
currAlt = alt;
}
planeOrient.setRoll(roll);
planeOrient.setTilt(pitch);
planeOrient.setHeading(yaw);
planeLoc.setLatitude(lat);
planeLoc.setLongitude(lon);
planeLoc.setAltitude(alt);
}
function failureCallback(object) {
function goHome()
{
var currView = ge.getView().copyAsLookAt(ge.ALTITUDE_ABSOLUTE);
currView.setLatitude(homeLat);
currView.setLongitude(homeLon);
currView.setAltitude(homeAlt);
currView.setRange(homeViewRange);
currView.setTilt(currTilt);
ge.getView().setAbstractView(currView);
}
</script>
function setCurrentAircraft(id)
{
currAircraft = id;
}
function enableFollowing(follow)
{
followEnabled = follow;
}
function updateFollowAircraft()
{
if (followEnabled)
{
currView = ge.getView().copyAsLookAt(ge.ALTITUDE_ABSOLUTE);
currView.setLatitude(currLat);
currView.setLongitude(currLon);
currView.setAltitude(currAlt);
currView.setRange(currViewRange);
currView.setTilt(currFollowTilt);
ge.getView().setAbstractView(currView);
}
}
function failureCallback(object)
{
}
</script>
<style type="text/css">
html, body {
margin: 0;

4
lib/QMapControl/src/mapnetwork.cpp

@ -95,7 +95,9 @@ namespace qmapcontrol @@ -95,7 +95,9 @@ namespace qmapcontrol
}
else
{
qDebug() << "NETWORK_PIXMAP_ERROR: " << ax;
// QGC FIXME Error is currently undetected
// TODO Error is currently undetected
//qDebug() << "NETWORK_PIXMAP_ERROR: " << ax;
}
}

BIN
models/ascent-park-glider.skp

Binary file not shown.

BIN
models/multiplex-easyglider.skp

Binary file not shown.

BIN
models/multiplex-twinstar.skp

Binary file not shown.

BIN
models/walkera-4g6.skp

Binary file not shown.

4
qgroundcontrol.pri

@ -80,6 +80,8 @@ macx { @@ -80,6 +80,8 @@ macx {
QMAKE_PRE_LINK += && cp -rf $$BASEDIR/audio $$DESTDIR/qgroundcontrol.app/Contents/MacOs/.
# Copy google earth starter file
QMAKE_PRE_LINK += && cp -f $$BASEDIR/images/earth.html $$DESTDIR/qgroundcontrol.app/Contents/MacOs/.
# Copy model files
QMAKE_PRE_LINK += && cp -f $$BASEDIR/models/*.skp $$DESTDIR/qgroundcontrol.app/Contents/MacOs/.
exists(/Library/Frameworks/osg.framework):exists(/Library/Frameworks/OpenThreads.framework) {
# No check for GLUT.framework since it's a MAC default
@ -278,6 +280,8 @@ win32-msvc2008 { @@ -278,6 +280,8 @@ win32-msvc2008 {
message(Building for Windows Visual Studio 2008 (32bit))
CONFIG += qaxcontainer
# Special settings for debug
#CONFIG += CONSOLE

9
qgroundcontrol.pro

@ -141,7 +141,8 @@ FORMS += src/ui/MainWindow.ui \ @@ -141,7 +141,8 @@ FORMS += src/ui/MainWindow.ui \
src/ui/QGCRemoteControlView.ui \
src/ui/QMap3D.ui \
src/ui/QGCWebView.ui \
src/ui/map3D/QGCGoogleEarthView.ui
src/ui/map3D/QGCGoogleEarthView.ui \
src/ui/map3D/QGCGoogleEarthViewWin.ui
# src/ui/WaypointGlobalView.ui
INCLUDEPATH += src \
@ -234,7 +235,8 @@ HEADERS += src/MG.h \ @@ -234,7 +235,8 @@ HEADERS += src/MG.h \
src/ui/RadioCalibration/AbstractCalibrator.h \
src/comm/QGCMAVLink.h \
src/ui/QGCWebView.h \
src/ui/map3D/QGCGoogleEarthView.h
src/ui/map3D/QGCGoogleEarthView.h \
src/ui/map3D/QGCWebPage.h
contains(DEPENDENCIES_PRESENT, osg) {
@ -336,7 +338,8 @@ SOURCES += src/main.cc \ @@ -336,7 +338,8 @@ SOURCES += src/main.cc \
src/ui/RadioCalibration/AbstractCalibrator.cc \
src/ui/RadioCalibration/RadioCalibrationData.cc \
src/ui/QGCWebView.cc \
src/ui/map3D/QGCGoogleEarthView.cc
src/ui/map3D/QGCGoogleEarthView.cc \
src/ui/map3D/QGCWebPage.cc
contains(DEPENDENCIES_PRESENT, osg) {
message("Including sources for OpenSceneGraph")

4
src/uas/UAS.cc

@ -76,6 +76,9 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(), @@ -76,6 +76,9 @@ UAS::UAS(MAVLinkProtocol* protocol, int id) : UASInterface(),
localX(0),
localY(0),
localZ(0),
latitude(0),
longitude(0),
altitude(0),
roll(0),
pitch(0),
yaw(0),
@ -776,6 +779,7 @@ void UAS::sendMessage(LinkInterface* link, mavlink_message_t message) @@ -776,6 +779,7 @@ void UAS::sendMessage(LinkInterface* link, mavlink_message_t message)
uint8_t buffer[MAVLINK_MAX_PACKET_LEN];
// Write message into buffer, prepending start sign
int len = mavlink_msg_to_send_buffer(buffer, &message);
mavlink_finalize_message_chan(&message, mavlink->getSystemId(), mavlink->getComponentId(), link->getId(), message.len);
// If link is connected
if (link->isConnected())
{

6
src/uas/UAS.h

@ -82,6 +82,9 @@ public: @@ -82,6 +82,9 @@ public:
double getLocalX() const { return localX; };
double getLocalY() const { return localY; };
double getLocalZ() const { return localZ; };
double getLat() const { return latitude; };
double getLon() const { return longitude; };
double getAlt() const { return altitude; };
double getRoll() const { return roll; };
double getPitch() const { return pitch; };
@ -139,6 +142,9 @@ protected: @@ -139,6 +142,9 @@ protected:
double localX;
double localY;
double localZ;
double latitude;
double longitude;
double altitude;
double roll;
double pitch;
double yaw;

4
src/uas/UASInterface.h

@ -70,6 +70,10 @@ public: @@ -70,6 +70,10 @@ public:
virtual double getLocalY() const = 0;
virtual double getLocalZ() const = 0;
virtual double getLat() const = 0;
virtual double getLon() const = 0;
virtual double getAlt() const = 0;
virtual double getRoll() const = 0;
virtual double getPitch() const = 0;
virtual double getYaw() const = 0;

87
src/ui/map3D/QGCGoogleEarthView.cc

@ -1,13 +1,47 @@ @@ -1,13 +1,47 @@
#include <QWebFrame>
#include <QWebPage>
#include <QDebug>
#include "QGCGoogleEarthView.h"
#include "QGCWebPage.h"
#include "UASManager.h"
#if (defined Q_OS_WIN) && !(defined __MINGW32__)
#else
#include "ui_QGCGoogleEarthView.h"
#endif
QGCGoogleEarthView::QGCGoogleEarthView(QWidget *parent) :
QWidget(parent),
ui(new Ui::QGCGoogleEarthView)
QWidget(parent),
updateTimer(new QTimer(this)),
mav(NULL),
followCamera(true),
#if (defined Q_OS_WIN) && !(defined __MINGW32__)
webViewWin(new QGCWebAxWidget(this)),
#else
ui(new Ui::QGCGoogleEarthView)
#endif
{
#if (defined Q_OS_WIN) && !(defined __MINGW32__)
// Create layout and attach webViewWin
#else
ui->setupUi(this);
ui->webView->setPage(new QGCWebPage(ui->webView));
ui->webView->settings()->setAttribute(QWebSettings::PluginsEnabled, true);
ui->webView->load(QUrl("earth.html"));
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
connect(updateTimer, SIGNAL(timeout()), this, SLOT(updateState()));
updateTimer->start(200);
#endif
// Get list of available 3D models
// Load HTML file
// Parse for model links
// Populate model list
}
QGCGoogleEarthView::~QGCGoogleEarthView()
@ -15,6 +49,55 @@ QGCGoogleEarthView::~QGCGoogleEarthView() @@ -15,6 +49,55 @@ QGCGoogleEarthView::~QGCGoogleEarthView()
delete ui;
}
void QGCGoogleEarthView::setActiveUAS(UASInterface* uas)
{
mav = uas;
}
void QGCGoogleEarthView::updateState()
{
if (ui->webView->page()->currentFrame()->evaluateJavaScript("isInitialized();").toBool())
{
static bool initialized = false;
if (!initialized)
{
ui->webView->page()->currentFrame()->evaluateJavaScript("setGCSHome(22.679833,8.549444, 470);");
initialized = true;
}
int uasId = 0;
double lat = 22.679833;
double lon = 8.549444;
double alt = 470.0;
float roll = 0.0f;
float pitch = 0.0f;
float yaw = 0.0f;
if (mav)
{
uasId = mav->getUASID();
lat = mav->getLat();
lon = mav->getLon();
alt = mav->getAlt();
roll = mav->getRoll();
pitch = mav->getPitch();
yaw = mav->getYaw();
}
// ui->webView->page()->currentFrame()->evaluateJavaScript(QString("setAircraftPosition(%1, %2, %3, %4);")
// .arg(uasId)
// .arg(lat)
// .arg(lon)
// .arg(alt));
// //ui->webView->page()->currentFrame()->evaluateJavaScript(QString("drawAndCenter(%1, %2, %3, %4, '%5', %6, %7, %8, %9, %10, %11);").arg(lat).arg(lon).arg(alt).arg("true").arg("ff0000ff").arg("1").arg("true").arg("true").arg(yaw).arg(pitch).arg(roll));
if (followCamera)
{
ui->webView->page()->currentFrame()->evaluateJavaScript(QString("updateFollowAircraft()"));
//ui->webView->page()->currentFrame()->evaluateJavaScript(QString("followAircraft(%1);").arg(mav->getUASID()));
}
}
}
void QGCGoogleEarthView::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);

39
src/ui/map3D/QGCGoogleEarthView.h

@ -2,10 +2,37 @@ @@ -2,10 +2,37 @@
#define QGCGOOGLEEARTHVIEW_H
#include <QWidget>
#include <QTimer>
#include <UASInterface.h>
#if (defined Q_OS_WIN) && !(defined __MINGW32__)
QGCWebAxWidget* webViewWin;
#include <ActiveQt/QAxWidget>
#include "windows.h"
class WebAxWidget : public QAxWidget
{
public:
WebAxWidget(QWidget* parent = 0, Qt::WindowFlags f = 0)
: QAxWidget(parent, f)
{
}
protected:
virtual bool translateKeyEvent(int message, int keycode) const
{
if (message >= WM_KEYFIRST && message <= WM_KEYLAST)
return true;
else
return QAxWidget::translateKeyEvent(message, keycode);
}
};
#else
namespace Ui {
class QGCGoogleEarthView;
}
#endif
class QGCGoogleEarthView : public QWidget
{
@ -15,11 +42,23 @@ public: @@ -15,11 +42,23 @@ public:
explicit QGCGoogleEarthView(QWidget *parent = 0);
~QGCGoogleEarthView();
public slots:
/** @brief Update the internal state. Does not trigger a redraw */
void updateState();
/** @brief Set the currently selected UAS */
void setActiveUAS(UASInterface* uas);
protected:
void changeEvent(QEvent *e);
QTimer* updateTimer;
UASInterface* mav;
bool followCamera;
#if (defined Q_OS_WIN) && !(defined __MINGW32__)
#else
private:
Ui::QGCGoogleEarthView *ui;
#endif
};
#endif // QGCGOOGLEEARTHVIEW_H

21
src/ui/map3D/QGCGoogleEarthViewWin.ui

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
<ui version="4.0" >
<author></author>
<comment></comment>
<exportmacro></exportmacro>
<class>Form</class>
<widget class="QWidget" name="Form" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
</widget>
<pixmapfunction></pixmapfunction>
<connections/>
</ui>

12
src/ui/map3D/QGCWebPage.cc

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
#include "QGCWebPage.h"
#include <QDebug>
QGCWebPage::QGCWebPage(QObject *parent) :
QWebPage(parent)
{
}
void QGCWebPage::javaScriptConsoleMessage ( const QString & message, int lineNumber, const QString & sourceID )
{
qDebug() << "JAVASCRIPT: " << lineNumber << sourceID << message;
}

21
src/ui/map3D/QGCWebPage.h

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
#ifndef QGCWEBPAGE_H
#define QGCWEBPAGE_H
#include <QWebPage>
class QGCWebPage : public QWebPage
{
Q_OBJECT
public:
explicit QGCWebPage(QObject *parent = 0);
signals:
public slots:
protected:
void javaScriptConsoleMessage ( const QString & message, int lineNumber, const QString & sourceID );
};
#endif // QGCWEBPAGE_H
Loading…
Cancel
Save