Commit 03f79989 authored by pixhawk's avatar pixhawk

Merge branch 'dev-mac' of github.com:pixhawk/qgroundcontrol into dev

parents 0683b989 e2261020
......@@ -8,6 +8,7 @@ Info.plist
obj
*.log
*~
*~.skp
bin/*.exe
bin/*.txt
bin/mac
......
......@@ -74,11 +74,39 @@ Done.
Windows
=======
DETAILED STEPS BELOW THE VISUAL STUDIO 2010 NOTES.
GNU GCC / MINGW IS UNTESTED, COULD WORK
VISUAL STUDIO 2008 / 2010 EXPRESS EDITION IS FREE!
-------------------------------------------------------------------------------------
VISUAL STUDIO 2010 NOTES (VS 2008 runs out-of-the-box, just follow the steps below):
For use of Qt 4x with Visual Studio 2010 Add-in.
Visual studio adds automatically certain defines that are wrong and cause errors.
To resolve this, execute these steps:
In the projects properties -> C/C++ ->preprocessor change:
in DEBUG:
delete QT_NO_DEBUG
in both (DEBUG / RELEASE):
delete QT_NO_DYNAMIC_CAST
-------------------------------------------------------------------------------------
Steps for Visual Studio 2008 / 2010. (VS 2008 is easier, VS 2010 only recommended for
expert developers)
Windows XP/7:
1) Download and install the QT SDK for Windows from http://qt.nokia.com/downloads/ (Visual Studio 2008 version)
1) Download and install the Qt SDK for Windows from http://qt.nokia.com/downloads/ (Visual Studio 2008 version) OR download Qt source and compile with VS 2010
2) Download and install Visual Studio 2008 Express Edition (free)
2) Download and install Visual Studio 2008 Express Edition (free) OR VS 2010 Express Edition
3) Go to the source folder of QGroundControl with the Qt 4.7.x Command Prompt tool (from the applications menu)
......
<PropertyList>
<generic>
<output>
<line_separator>newline</line_separator>
<var_separator>,</var_separator>
<chunk>
<name>lat</name>
<type>float</type>
<format>%+1.8f</format>
<node>/position/latitude-deg</node>
</chunk>
<chunk>
<name>lon</name>
<type>float</type>
<format>%+1.8f</format>
<node>/position/longitude-deg</node>
</chunk>
<chunk>
<name>alt</name>
<type>float</type>
<format>%+1.4f</format>
<node>/position/altitude-ft</node>
</chunk>
<chunk>
<name>speed</name>
<type>float</type>
<format>%2.3f</format>
<node>/velocities/groundspeed-kt</node>
</chunk>
<chunk>
<name>airspeed</name>
<type>float</type>
<format>%2.3f</format>
<node>/velocities/airspeed-kt</node>
</chunk>
<chunk>
<name>pitch</name>
<type>float</type>
<format>%+1.3f</format>
<node>/orientation/pitch-deg</node>
</chunk>
<chunk>
<name>roll</name>
<type>float</type>
<format>%+1.3f</format>
<node>/orientation/roll-deg</node>
</chunk>
<chunk>
<name>heading</name>
<type>float</type>
<format>%+1.3f</format>
<node>/orientation/heading-deg</node>
</chunk>
<chunk>
<name>v_n</name>
<type>float</type>
<format>%2.3f</format>
<node>/velocities/speed-north-fps</node>
</chunk>
<chunk>
<name>v_e</name>
<type>float</type>
<format>%2.3f</format>
<node>/velocities/speed-east-fps</node>
</chunk>
<chunk>
<name>v_d</name>
<type>float</type>
<format>%2.3f</format>
<node>/velocities/speed-down-fps</node>
</chunk>
<chunk>
<name>rate_phi</name>
<type>float</type>
<format>%2.3f</format>
<node>/orientation/roll-rate-degps</node>
</chunk>
<chunk>
<name>rate_theta</name>
<type>float</type>
<format>%2.3f</format>
<node>/orientation/pitch-rate-degps</node>
</chunk>
<chunk>
<name>rate_psi</name>
<type>float</type>
<format>%2.3f</format>
<node>/orientation/yaw-rate-degps</node>
</chunk>
</output>
<input>
<line_separator>newline</line_separator>
<var_separator>,</var_separator>
<chunk>
<name>pitch</name>
<type>float</type>
<format>%+1.3f</format>
<node>/autopilot/settings/target-pitch-deg</node>
</chunk>
<chunk>
<name>roll</name>
<type>float</type>
<format>%+1.3f</format>
<node>/autopilot/settings/target-roll-deg</node>
</chunk>
<chunk>
<name>throttle</name>
<type>float</type>
<format>%+1.3f</format>
<node>/controls/engines/engine/throttle</node>
</chunk>
<chunk>
<name>lat</name>
<type>float</type>
<format>%+1.8f</format>
<node>/sim/view/target/latitude-deg</node>
</chunk>
<chunk>
<name>lon</name>
<type>float</type>
<format>%+1.8f</format>
<node>/sim/view/target/longitude-deg</node>
</chunk>
<chunk>
<name>alt</name>
<type>float</type>
<format>%+1.4f</format>
<node>/sim/view/target/alt</node>
</chunk>
</input>
</generic>
</PropertyList>
B໿SketchUp Model૿{8.0.4810}Ƕ『時҆✱闊ÿ主乁￿ 噃牥楳湯慍ー￾䌉䄀爀挀䌀甀爀瘀攀Ā＀￾䌊䄀琀琀爀椀戀甀琀攀＀￾䌓䄀琀琀爀椀戀甀琀攀䌀漀渀琀愀椀渀攀爀＀￾䌏䄀琀琀爀椀戀甀琀攀一愀洀攀搀Ā＀￾䌐䈀愀挀欀最爀漀甀渀搀䤀洀愀最攀਀＀￾䌇䌀愀洀攀爀愀Ԁ＀￾䌊䌀漀洀瀀漀渀攀渀琀଀＀￾䌒䌀漀洀瀀漀渀攀渀琀䈀攀栀愀瘀椀漀爀Ԁ＀￾䌔䌀漀洀瀀漀渀攀渀琀䐀攀昀椀渀椀琀椀漀渀਀＀￾䌒䌀漀洀瀀漀渀攀渀琀䤀渀猀琀愀渀挀攀Ѐ＀￾䌕䌀漀渀猀琀爀甀挀琀椀漀渀䜀攀漀洀攀琀爀礀＀￾䌑䌀漀渀猀琀爀甀挀琀椀漀渀䰀椀渀攀Ā＀￾䌒䌀漀渀猀琀爀甀挀琀椀漀渀倀漀椀渀琀＀￾䌆䌀甀爀瘀攀Ѐ＀￾䌏䐀攀昀椀渀椀琀椀漀渀䰀椀猀琀＀￾䌄䐀椀戀̀＀￾䌊䐀椀洀攀渀猀椀漀渀Ā＀￾䌐䐀椀洀攀渀猀椀漀渀䰀椀渀攀愀爀؀＀￾䌐䐀椀洀攀渀猀椀漀渀刀愀搀椀愀氀Ȁ＀￾䌏䐀椀洀攀渀猀椀漀渀匀琀礀氀攀Ѐ＀￾䌏䐀爀愀眀椀渀最䔀氀攀洀攀渀琀ऀ＀￾䌅䔀搀最攀Ȁ＀￾䌈䔀搀最攀唀猀攀Ā＀￾䌇䔀渀琀椀琀礀̀＀￾䌅䘀愀挀攀̀＀￾䌒䘀愀挀攀吀攀砀琀甀爀攀䌀漀漀爀搀猀Ѐ＀￾䌌䘀漀渀琀䴀愀渀愀最攀爀＀￾䌆䜀爀漀甀瀀Ā＀￾䌆䤀洀愀最攀Ā＀￾䌆䰀愀礀攀爀Ȁ＀￾䌍䰀愀礀攀爀䴀愀渀愀最攀爀Ѐ＀￾䌅䰀漀漀瀀Ā＀￾䌉䴀愀琀攀爀椀愀氀ఀ＀￾䌐䴀愀琀攀爀椀愀氀䴀愀渀愀最攀爀Ѐ＀￾䌉倀愀最攀䰀椀猀琀Ā＀￾䌋倀漀氀礀氀椀渀攀㌀搀＀￾䌍刀攀氀愀琀椀漀渀猀栀椀瀀＀￾䌐刀攀氀愀琀椀漀渀猀栀椀瀀䴀愀瀀＀￾䌑刀攀渀搀攀爀椀渀最伀瀀琀椀漀渀猀␀＀￾䌍匀攀挀琀椀漀渀倀氀愀渀攀Ȁ＀￾䌋匀栀愀搀漀眀䤀渀昀漀܀＀￾䌇匀欀䘀漀渀琀Ā＀￾䌉匀欀攀琀挀栀䌀匀＀￾䌎匀欀攀琀挀栀唀瀀䴀漀搀攀氀ᘀ＀￾䌍匀欀攀琀挀栀唀瀀倀愀最攀Ā＀￾䌉匀欀瀀匀琀礀氀攀Ā＀￾䌐匀欀瀀匀琀礀氀攀䴀愀渀愀最攀爀Ȁ＀￾䌅吀攀砀琀ऀ＀￾䌊吀攀砀琀匀琀礀氀攀Ԁ＀￾䌈吀攀砀琀甀爀攀؀＀￾䌊吀栀甀洀戀渀愀椀氀Ā＀￾䌇嘀攀爀琀攀砀＀￾䌉嘀椀攀眀倀愀最攀ఀ＀￾䌊圀愀琀攀爀洀愀爀欀Ā＀￾䌑圀愀琀攀爀洀愀爀欀䴀愀渀愀最攀爀Ȁ＀￾䔒渀搀ⴀ伀昀ⴀ嘀攀爀猀椀漀渀ⴀ䴀愀瀀Ȁ뀀Ā＀ϿЀ䌀楄Ѣꨀ褀乐േᨊ
......
B໿SketchUp Model૿{8.0.4810}∳꛺䧕灁骨鎠讠ÿ侘乁￿ 噃牥楳湯慍ー￾䌉䄀爀挀䌀甀爀瘀攀Ā＀￾䌊䄀琀琀爀椀戀甀琀攀＀￾䌓䄀琀琀爀椀戀甀琀攀䌀漀渀琀愀椀渀攀爀＀￾䌏䄀琀琀爀椀戀甀琀攀一愀洀攀搀Ā＀￾䌐䈀愀挀欀最爀漀甀渀搀䤀洀愀最攀਀＀￾䌇䌀愀洀攀爀愀Ԁ＀￾䌊䌀漀洀瀀漀渀攀渀琀଀＀￾䌒䌀漀洀瀀漀渀攀渀琀䈀攀栀愀瘀椀漀爀Ԁ＀￾䌔䌀漀洀瀀漀渀攀渀琀䐀攀昀椀渀椀琀椀漀渀਀＀￾䌒䌀漀洀瀀漀渀攀渀琀䤀渀猀琀愀渀挀攀Ѐ＀￾䌕䌀漀渀猀琀爀甀挀琀椀漀渀䜀攀漀洀攀琀爀礀＀￾䌑䌀漀渀猀琀爀甀挀琀椀漀渀䰀椀渀攀Ā＀￾䌒䌀漀渀猀琀爀甀挀琀椀漀渀倀漀椀渀琀＀￾䌆䌀甀爀瘀攀Ѐ＀￾䌏䐀攀昀椀渀椀琀椀漀渀䰀椀猀琀＀￾䌄䐀椀戀̀＀￾䌊䐀椀洀攀渀猀椀漀渀Ā＀￾䌐䐀椀洀攀渀猀椀漀渀䰀椀渀攀愀爀؀＀￾䌐䐀椀洀攀渀猀椀漀渀刀愀搀椀愀氀Ȁ＀￾䌏䐀椀洀攀渀猀椀漀渀匀琀礀氀攀Ѐ＀￾䌏䐀爀愀眀椀渀最䔀氀攀洀攀渀琀ऀ＀￾䌅䔀搀最攀Ȁ＀￾䌈䔀搀最攀唀猀攀Ā＀￾䌇䔀渀琀椀琀礀̀＀￾䌅䘀愀挀攀̀＀￾䌒䘀愀挀攀吀攀砀琀甀爀攀䌀漀漀爀搀猀Ѐ＀￾䌌䘀漀渀琀䴀愀渀愀最攀爀＀￾䌆䜀爀漀甀瀀Ā＀￾䌆䤀洀愀最攀Ā＀￾䌆䰀愀礀攀爀Ȁ＀￾䌍䰀愀礀攀爀䴀愀渀愀最攀爀Ѐ＀￾䌅䰀漀漀瀀Ā＀￾䌉䴀愀琀攀爀椀愀氀ఀ＀￾䌐䴀愀琀攀爀椀愀氀䴀愀渀愀最攀爀Ѐ＀￾䌉倀愀最攀䰀椀猀琀Ā＀￾䌋倀漀氀礀氀椀渀攀㌀搀＀￾䌍刀攀氀愀琀椀漀渀猀栀椀瀀＀￾䌐刀攀氀愀琀椀漀渀猀栀椀瀀䴀愀瀀＀￾䌑刀攀渀搀攀爀椀渀最伀瀀琀椀漀渀猀␀＀￾䌍匀攀挀琀椀漀渀倀氀愀渀攀Ȁ＀￾䌋匀栀愀搀漀眀䤀渀昀漀܀＀￾䌇匀欀䘀漀渀琀Ā＀￾䌉匀欀攀琀挀栀䌀匀＀￾䌎匀欀攀琀挀栀唀瀀䴀漀搀攀氀ᘀ＀￾䌍匀欀攀琀挀栀唀瀀倀愀最攀Ā＀￾䌉匀欀瀀匀琀礀氀攀Ā＀￾䌐匀欀瀀匀琀礀氀攀䴀愀渀愀最攀爀Ȁ＀￾䌅吀攀砀琀ऀ＀￾䌊吀攀砀琀匀琀礀氀攀Ԁ＀￾䌈吀攀砀琀甀爀攀؀＀￾䌊吀栀甀洀戀渀愀椀氀Ā＀￾䌇嘀攀爀琀攀砀＀￾䌉嘀椀攀眀倀愀最攀ఀ＀￾䌊圀愀琀攀爀洀愀爀欀Ā＀￾䌑圀愀琀攀爀洀愀爀欀䴀愀渀愀最攀爀Ȁ＀￾䔒渀搀ⴀ伀昀ⴀ嘀攀爀猀椀漀渀ⴀ䴀愀瀀Ȁ뀀Ā＀ϿЀ䌀楄Ѣ⼀褀乐േᨊ
price quantity
210 81
250 73
280 64
300 61
320 50
340 46
360 45
380 44
400 43
420 39
440 36
......@@ -236,6 +236,7 @@ HEADERS += src/MG.h \
src/comm/ProtocolInterface.h \
src/comm/MAVLinkProtocol.h \
src/comm/AS4Protocol.h \
src/comm/QGCFlightGearLink.h \
src/ui/CommConfigurationWindow.h \
src/ui/SerialConfigurationWindow.h \
src/ui/MainWindow.h \
......@@ -364,6 +365,7 @@ SOURCES += src/main.cc \
src/comm/SerialSimulationLink.cc \
src/comm/MAVLinkProtocol.cc \
src/comm/AS4Protocol.cc \
src/comm/QGCFlightGearLink.cc \
src/ui/CommConfigurationWindow.cc \
src/ui/SerialConfigurationWindow.cc \
src/ui/MainWindow.cc \
......
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 class MAVLinkXMLParserV10
* @author Lorenz Meier <mail@qgroundcontrol.org>
*/
#ifndef MAVLINKXMLPARSERV10_H
#define MAVLINKXMLPARSERV10_H
#include <QObject>
#include <QDomDocument>
#include <QString>
/**
* @brief MAVLink micro air vehicle protocol generator
*
* MAVLink is a generic communication protocol for micro air vehicles.
* for more information, please see the official website.
* @ref http://pixhawk.ethz.ch/software/mavlink/
**/
class MAVLinkXMLParserV10 : public QObject
{
Q_OBJECT
public:
MAVLinkXMLParserV10(QDomDocument* document, QString outputDirectory, QObject* parent=0);
MAVLinkXMLParserV10(QString document, QString outputDirectory, QObject* parent=0);
~MAVLinkXMLParserV10();
public slots:
/** @brief Parse XML and generate C files */
bool generate();
signals:
/** @brief Status message on the parsing */
void parseState(QString message);
protected:
QDomDocument* doc;
QString outputDirName;
QString fileName;
};
#endif // MAVLINKXMLPARSERV10_H
......@@ -29,6 +29,7 @@ FORMS += ui/XMLCommProtocolWidget.ui
HEADERS += \
ui/XMLCommProtocolWidget.h \
generator/MAVLinkXMLParser.h \
generator/MAVLinkXMLParserV10.h \
ui/DomItem.h \
ui/DomModel.h \
ui/QGCMAVLinkTextEdit.h
......@@ -37,6 +38,7 @@ SOURCES += \
ui/DomItem.cc \
ui/DomModel.cc \
generator/MAVLinkXMLParser.cc \
generator/MAVLinkXMLParserV10.cc \
ui/QGCMAVLinkTextEdit.cc
RESOURCES += mavlinkgen.qrc
......@@ -6,6 +6,7 @@
#include "XMLCommProtocolWidget.h"
#include "ui_XMLCommProtocolWidget.h"
#include "MAVLinkXMLParser.h"
#include "MAVLinkXMLParserV10.h"
#include <QDebug>
#include <iostream>
......@@ -131,18 +132,37 @@ void XMLCommProtocolWidget::generate()
// Syntax check already gives output
return;
}
MAVLinkXMLParser* parser = new MAVLinkXMLParser(m_ui->fileNameLabel->text().trimmed(), m_ui->outputDirNameLabel->text().trimmed());
connect(parser, SIGNAL(parseState(QString)), m_ui->compileLog, SLOT(appendHtml(QString)));
bool result = parser->generate();
if (result) {
MAVLinkXMLParser* parser = NULL;
MAVLinkXMLParserV10* parserV10 = NULL;
bool result = false;
if (m_ui->versionComboBox->currentIndex() == 0)
{
MAVLinkXMLParser* parser = new MAVLinkXMLParser(m_ui->fileNameLabel->text().trimmed(), m_ui->outputDirNameLabel->text().trimmed());
connect(parser, SIGNAL(parseState(QString)), m_ui->compileLog, SLOT(appendHtml(QString)));
result = parser->generate();
}
else if (m_ui->versionComboBox->currentIndex() == 1)
{
MAVLinkXMLParserV10* parserV10 = new MAVLinkXMLParserV10(m_ui->fileNameLabel->text().trimmed(), m_ui->outputDirNameLabel->text().trimmed());
connect(parserV10, SIGNAL(parseState(QString)), m_ui->compileLog, SLOT(appendHtml(QString)));
result = parserV10->generate();
}
if (result)
{
QMessageBox msgBox;
msgBox.setText(QString("The C code / headers have been generated in folder\n%1").arg(m_ui->outputDirNameLabel->text().trimmed()));
msgBox.exec();
} else {
}
else
{
QMessageBox::critical(this, tr("C code generation failed, please see the compile log for further information"), QString("The C code / headers could not be written to folder\n%1").arg(m_ui->outputDirNameLabel->text().trimmed()), QMessageBox::Ok);
}
delete parser;
if (parser) delete parser;
if (parserV10) delete parserV10;
}
void XMLCommProtocolWidget::save()
......
......@@ -13,7 +13,7 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout" rowstretch="1,1,100,1,1,1" columnstretch="1,1,1,100">
<layout class="QGridLayout" name="gridLayout" rowstretch="1,1,100,1,1,1,0" columnstretch="1,1,1,100">
<property name="topMargin">
<number>6</number>
</property>
......@@ -51,12 +51,12 @@
<string>Select input file</string>
</property>
<property name="icon">
<iconset resource="../mavlinkgen.qrc">
<iconset resource="../../../../qgroundcontrol.qrc">
<normaloff>:/images/status/folder-open.svg</normaloff>:/images/status/folder-open.svg</iconset>
</property>
</widget>
</item>
<item row="0" column="3" rowspan="6">
<item row="0" column="3" rowspan="7">
<widget class="QGCMAVLinkTextEdit" name="xmlTextView">
<property name="minimumSize">
<size>
......@@ -97,49 +97,70 @@
<string>Select directory</string>
</property>
<property name="icon">
<iconset resource="../mavlinkgen.qrc">
<iconset resource="../../../../qgroundcontrol.qrc">
<normaloff>:/images/status/folder-open.svg</normaloff>:/images/status/folder-open.svg</iconset>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<item row="3" column="0" colspan="3">
<widget class="QTreeView" name="xmlTreeView"/>
</item>
<item row="3" column="0" colspan="2">
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>Compile Output</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<item row="5" column="0" colspan="3">
<widget class="QPlainTextEdit" name="compileLog"/>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="validXMLLabel">
<property name="text">
<string>No file loaded</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QPushButton" name="saveButton">
<property name="text">
<string>Save file</string>
</property>
</widget>
</item>
<item row="5" column="2">
<item row="6" column="2">
<widget class="QPushButton" name="generateButton">
<property name="text">
<string>Save and generate</string>
</property>
<property name="icon">
<iconset resource="../mavlinkgen.qrc">
<iconset resource="../../../../qgroundcontrol.qrc">
<normaloff>:/images/categories/applications-system.svg</normaloff>:/images/categories/applications-system.svg</iconset>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Select MAVLink Version</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="versionComboBox">
<item>
<property name="text">
<string>MAVLink v0.9 (-Aug'10)</string>
</property>
</item>
<item>
<property name="text">
<string>MAVLink v1.0 (Sept'10+)</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
<customwidgets>
......@@ -150,7 +171,7 @@
</customwidget>
</customwidgets>
<resources>
<include location="../mavlinkgen.qrc"/>
<include location="../../../../qgroundcontrol.qrc"/>
</resources>
<connections/>
</ui>
......@@ -17,7 +17,6 @@
#include <QSettings>
#include <QDesktopServices>
//#include "MG.h"
#include "MAVLinkProtocol.h"
#include "UASInterface.h"
#include "UASManager.h"
......@@ -28,7 +27,6 @@
#include "ArduPilotMegaMAV.h"
#include "configuration.h"
#include "LinkManager.h"
//#include "MainWindow.h"
#include "QGCMAVLink.h"
#include "QGCMAVLinkUASFactory.h"
#include "QGC.h"
......@@ -182,14 +180,14 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
unsigned int decodeState = mavlink_parse_char(link->getId(), (uint8_t)(b.at(position)), &message, &status);
if (decodeState == 1) {
#ifdef MAVLINK_MESSAGE_LENGTHS
const uint8_t message_lengths[] = MAVLINK_MESSAGE_LENGTHS;
if (message.msgid >= sizeof(message_lengths) ||
message.len != message_lengths[message.msgid]) {
qDebug() << "MAVLink message " << message.msgid << " length incorrect (was " << message.len << " expected " << message_lengths[message.msgid] << ")";
continue;
}
#endif
//#ifdef MAVLINK_MESSAGE_LENGTHS
// const uint8_t message_lengths[] = MAVLINK_MESSAGE_LENGTHS;
// if (message.msgid >= sizeof(message_lengths) ||
// message.len != message_lengths[message.msgid]) {
// qDebug() << "MAVLink message " << message.msgid << " length incorrect (was " << message.len << " expected " << message_lengths[message.msgid] << ")";
// continue;
// }
//#endif
// Log data
if (m_loggingEnabled && m_logfile) {
const int len = MAVLINK_MAX_PACKET_LEN+sizeof(quint64);
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2011 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 UDP connection (server) for unmanned vehicles
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#include <QTimer>
#include <QList>
#include <QDebug>
#include <QMutexLocker>
#include <iostream>
#include "QGCFlightGearLink.h"
#include "QGC.h"
#include <QHostInfo>
QGCFlightGearLink::QGCFlightGearLink(QString remoteHost, QHostAddress host, quint16 port)
{
this->host = host;
this->port = port;
this->connectState = false;
this->currentPort = 49000;
// Set unique ID and add link to the list of links
this->name = tr("FlightGear Link (port:%1)").arg(port);
setRemoteHost(remoteHost);
connect(&refreshTimer, SIGNAL(timeout()), this, SLOT(sendUAVUpdate()));
refreshTimer.start(20); // 50 Hz UAV -> Simulation update rate
}
QGCFlightGearLink::~QGCFlightGearLink()
{
disconnect();
}
/**
* @brief Runs the thread
*
**/
void QGCFlightGearLink::run()
{
// forever
// {
// QGC::SLEEP::msleep(5000);
// }
exec();
}
void QGCFlightGearLink::setPort(int port)
{
this->port = port;
disconnectSimulation();
connectSimulation();
}
/**
* @param host Hostname in standard formatting, e.g. localhost:14551 or 192.168.1.1:14551
*/
void QGCFlightGearLink::setRemoteHost(const QString& host)
{
//qDebug() << "UDP:" << "ADDING HOST:" << host;
if (host.contains(":"))
{
//qDebug() << "HOST: " << host.split(":").first();
QHostInfo info = QHostInfo::fromName(host.split(":").first());
if (info.error() == QHostInfo::NoError)
{
// Add host
QList<QHostAddress> hostAddresses = info.addresses();
QHostAddress address;
for (int i = 0; i < hostAddresses.size(); i++)
{
// Exclude loopback IPv4 and all IPv6 addresses
if (!hostAddresses.at(i).toString().contains(":"))
{
address = hostAddresses.at(i);
}
}
currentHost = address;
//qDebug() << "Address:" << address.toString();
// Set port according to user input
currentPort = host.split(":").last().toInt();
}
}
else
{
QHostInfo info = QHostInfo::fromName(host);
if (info.error() == QHostInfo::NoError)
{
// Add host
currentHost = info.addresses().first();
}
}
}
void QGCFlightGearLink::updateGlobalPosition(quint64 time, double lat, double lon, double alt)
{
}
void QGCFlightGearLink::sendUAVUpdate()
{
// 37.613548,-122.357246,-9999.000000,0.000000,0.424000,297.899994,0.000000\n
// magnetos,aileron,elevator,rudder,throttle\n
float magnetos = 3.0f;
float aileron = 0.0f;
float elevator = 0.0f;
float rudder = 0.0f;
float throttle = 90.0f;
QString state("%1,%2,%3,%4,%5\n");
state = state.arg(magnetos).arg(aileron).arg(elevator).arg(rudder).arg(throttle);
writeBytes(state.toAscii().constData(), state.length());
}
void QGCFlightGearLink::writeBytes(const char* data, qint64 size)
{
//#define QGCFlightGearLink_DEBUG
#ifdef QGCFlightGearLink_DEBUG
QString bytes;
QString ascii;
for (int i=0; i<size; i++)
{
unsigned char v = data[i];
bytes.append(QString().sprintf("%02x ", v));
if (data[i] > 31 && data[i] < 127)
{
ascii.append(data[i]);
}
else
{
ascii.append(219);
}
}
qDebug() << "Sent" << size << "bytes to" << currentHost.toString() << ":" << currentPort << "data:";
qDebug() << bytes;
qDebug() << "ASCII:" << ascii;
#endif
socket->writeDatagram(data, size, currentHost, currentPort);
}
/**
* @brief Read a number of bytes from the interface.
*
* @param data Pointer to the data byte array to write the bytes to
* @param maxLength The maximum number of bytes to write
**/
void QGCFlightGearLink::readBytes()
{
const qint64 maxLength = 65536;
static char data[maxLength];
QHostAddress sender;
quint16 senderPort;
unsigned int s = socket->pendingDatagramSize();
if (s > maxLength) std::cerr << __FILE__ << __LINE__ << " UDP datagram overflow, allowed to read less bytes than datagram size" << std::endl;
socket->readDatagram(data, maxLength, &sender, &senderPort);
// FIXME TODO Check if this method is better than retrieving the data by individual processes
QByteArray b(data, s);
//emit bytesReceived(this, b);
// Print string
qDebug() << "FG LINK GOT:" << QString(b);
// // Echo data for debugging purposes
// std::cerr << __FILE__ << __LINE__ << "Received datagram:" << std::endl;
// int i;
// for (i=0; i<s; i++)
// {
// unsigned int v=data[i];
// fprintf(stderr,"%02x ", v);
// }
// std::cerr << std::endl;
}
/**
* @brief Get the number of bytes to read.
*
* @return The number of bytes to read
**/
qint64 QGCFlightGearLink::bytesAvailable()
{
return socket->pendingDatagramSize();
}
/**
* @brief Disconnect the connection.
*
* @return True if connection has been disconnected, false if connection couldn't be disconnected.
**/
bool QGCFlightGearLink::disconnectSimulation()
{
delete socket;
socket = NULL;
connectState = false;
emit flightGearDisconnected();
emit flightGearConnected(false);
return !connectState;
}
/**
* @brief Connect the connection.
*
* @return True if connection has been established, false if connection couldn't be established.
**/
bool QGCFlightGearLink::connectSimulation()
{
socket = new QUdpSocket(this);
//Check if we are using a multicast-address
// bool multicast = false;
// if (host.isInSubnet(QHostAddress("224.0.0.0"),4))
// {
// multicast = true;
// connectState = socket->bind(port, QUdpSocket::ShareAddress);
// }
// else
// {
connectState = socket->bind(host, port);
// }
//Provides Multicast functionality to UdpSocket
/* not working yet
if (multicast)
{
int sendingFd = socket->socketDescriptor();
if (sendingFd != -1)
{
// set up destination address
struct sockaddr_in sendAddr;
memset(&sendAddr,0,sizeof(sendAddr));
sendAddr.sin_family=AF_INET;
sendAddr.sin_addr.s_addr=inet_addr(HELLO_GROUP);
sendAddr.sin_port=htons(port);
// set TTL
unsigned int ttl = 1; // restricted to the same subnet
if (setsockopt(sendingFd, IPPROTO_IP, IP_MULTICAST_TTL, (unsigned int*)&ttl, sizeof(ttl) ) < 0)
{
std::cout << "TTL failed\n";
}
}
}
*/
//QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(readBytes()));
emit flightGearConnected(connectState);
if (connectState) {
emit flightGearConnected();
connectionStartTime = QGC::groundTimeUsecs()/1000;
}
start(HighPriority);
return connectState;
}
/**
* @brief Check if connection is active.
*
* @return True if link is connected, false otherwise.
**/
bool QGCFlightGearLink::isConnected()
{
return connectState;
}
QString QGCFlightGearLink::getName()
{
return name;
}
void QGCFlightGearLink::setName(QString name)
{
this->name = name;
// emit nameChanged(this->name);
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2011 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 UDP connection (server) for unmanned vehicles
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#ifndef QGCFLIGHTGEARLINK_H
#define QGCFLIGHTGEARLINK_H
#include <QString>
#include <QList>
#include <QMap>
#include <QMutex>
#include <QUdpSocket>
#include <QTimer>
#include <LinkInterface.h>
#include <configuration.h>
class QGCFlightGearLink : public QThread
{
Q_OBJECT
//Q_INTERFACES(QGCFlightGearLinkInterface:LinkInterface)
public:
QGCFlightGearLink(QString remoteHost=QString("127.0.0.1:49000"), QHostAddress host = QHostAddress::Any, quint16 port = 49005);
~QGCFlightGearLink();
bool isConnected();
qint64 bytesAvailable();
int getPort() const {
return port;
}
/**
* @brief The human readable port name
*/
QString getName();
void run();
public slots:
// void setAddress(QString address);
void setPort(int port);
/** @brief Add a new host to broadcast messages to */
void setRemoteHost(const QString& host);
void updateGlobalPosition(quint64 time, double lat, double lon, double alt);
void sendUAVUpdate();
// /** @brief Remove a host from broadcasting messages to */
// void removeHost(const QString& host);
// void readPendingDatagrams();
void readBytes();
/**
* @brief Write a number of bytes to the interface.
*
* @param data Pointer to the data byte array
* @param size The size of the bytes array
**/
void writeBytes(const char* data, qint64 length);
bool connectSimulation();
bool disconnectSimulation();
protected:
QString name;
QHostAddress host;
QHostAddress currentHost;
quint16 currentPort;
quint16 port;
int id;
QUdpSocket* socket;
bool connectState;
quint64 bitsSentTotal;
quint64 bitsSentCurrent;
quint64 bitsSentMax;
quint64 bitsReceivedTotal;
quint64 bitsReceivedCurrent;
quint64 bitsReceivedMax;
quint64 connectionStartTime;
QMutex statisticsMutex;
QMutex dataMutex;
QTimer refreshTimer;
void setName(QString name);
signals:
/**
* @brief This signal is emitted instantly when the link is connected
**/
void flightGearConnected();
/**
* @brief This signal is emitted instantly when the link is disconnected
**/
void flightGearDisconnected();
/**
* @brief This signal is emitted instantly when the link status changes
**/
void flightGearConnected(bool connected);
};
#endif // QGCFLIGHTGEARLINK_H
......@@ -86,7 +86,8 @@ void UDPLink::setPort(int port)
void UDPLink::addHost(const QString& host)
{
//qDebug() << "UDP:" << "ADDING HOST:" << host;
if (host.contains(":")) {
if (host.contains(":"))
{
//qDebug() << "HOST: " << host.split(":").first();
QHostInfo info = QHostInfo::fromName(host.split(":").first());
if (info.error() == QHostInfo::NoError)
......@@ -129,14 +130,18 @@ void UDPLink::removeHost(const QString& hostname)
QHostInfo info = QHostInfo::fromName(host);
QHostAddress address;
QList<QHostAddress> hostAddresses = info.addresses();
for (int i = 0; i < hostAddresses.size(); i++) {
for (int i = 0; i < hostAddresses.size(); i++)
{
// Exclude loopback IPv4 and all IPv6 addresses
if (!hostAddresses.at(i).toString().contains(":")) {
if (!hostAddresses.at(i).toString().contains(":"))
{
address = hostAddresses.at(i);
}
}
for (int i = 0; i < hosts.count(); ++i) {
if (hosts.at(i) == address) {
for (int i = 0; i < hosts.count(); ++i)
{
if (hosts.at(i) == address)
{
hosts.removeAt(i);
ports.removeAt(i);
}
......@@ -154,7 +159,8 @@ void UDPLink::writeBytes(const char* data, qint64 size)
#ifdef UDPLINK_DEBUG
QString bytes;
QString ascii;
for (int i=0; i<size; i++) {
for (int i=0; i<size; i++)
{
unsigned char v = data[i];
bytes.append(QString().sprintf("%02x ", v));
if (data[i] > 31 && data[i] < 127)
......@@ -183,7 +189,7 @@ void UDPLink::writeBytes(const char* data, qint64 size)
void UDPLink::readBytes()
{
const qint64 maxLength = 65536;
char data[maxLength];
static char data[maxLength];
QHostAddress sender;
quint16 senderPort;
......@@ -207,11 +213,14 @@ void UDPLink::readBytes()
// Add host to broadcast list if not yet present
if (!hosts.contains(sender)) {
if (!hosts.contains(sender))
{
hosts.append(sender);
ports.append(senderPort);
// ports->insert(sender, senderPort);
} else {
}
else
{
int index = hosts.indexOf(sender);
ports.replace(index, senderPort);
}
......
......@@ -2,7 +2,7 @@
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
(c) 2009 - 2011 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
......
This diff is collapsed.
......@@ -204,6 +204,8 @@ protected: //COMMENTS FOR TEST UNIT
QGCUASParamManager* paramManager; ///< Parameter manager class
QString shortStateText; ///< Short textual state description
QString shortModeText; ///< Short textual mode description
bool attitudeStamped; ///< Should arriving data be timestamped with the last attitude? This helps with broken system time clocks on the MAV
quint64 lastAttitude; ///< Timestamp of last attitude measurement
public:
/** @brief Set the current battery type */
......@@ -403,6 +405,8 @@ signals:
protected:
/** @brief Get the UNIX timestamp in milliseconds */
quint64 getUnixTime(quint64 time=0);
/** @brief Get the UNIX timestamp in milliseconds, ignore attitudeStamped mode */
quint64 getUnixReferenceTime(quint64 time);
protected slots:
/** @brief Write settings to disk */
......
......@@ -157,6 +157,11 @@ MainWindow::MainWindow(QWidget *parent):
joystickWidget = 0;
joystick = new JoystickInput();
// Connect flighgear test link
// FIXME MOVE INTO UAV OBJECT
fgLink = new QGCFlightGearLink();
fgLink->connectSimulation();
// Load Toolbar
toolBar = new QGCToolBar(this);
this->addToolBar(toolBar);
......
......@@ -75,6 +75,7 @@ This file is part of the QGROUNDCONTROL project
#include "SlugsPadCameraControl.h"
#include "UASControlParameters.h"
#include "QGCFlightGearLink.h"
class QGCMapTool;
......@@ -445,6 +446,7 @@ protected:
QGC_MAINWINDOW_STYLE currentStyle;
Qt::WindowStates windowStateVal;
bool lowPowerMode; ///< If enabled, QGC reduces the update rates of all widgets
QGCFlightGearLink* fgLink;
private:
Ui::MainWindow ui;
......
......@@ -55,6 +55,7 @@ void QGCToolBar::setActiveUAS(UASInterface* active)
disconnect(mav, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int,QString,QString)));
disconnect(mav, SIGNAL(nameChanged(QString)), this, SLOT(updateName(QString)));
disconnect(mav, SIGNAL(systemTypeSet(UASInterface*,uint)), this, SLOT(setSystemType(UASInterface*,uint)));
disconnect(mav, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(receiveTextMessage(int,int,int,QString)));
}
// Connect new system
......@@ -63,6 +64,7 @@ void QGCToolBar::setActiveUAS(UASInterface* active)
connect(active, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int,QString,QString)));
connect(active, SIGNAL(nameChanged(QString)), this, SLOT(updateName(QString)));
connect(active, SIGNAL(systemTypeSet(UASInterface*,uint)), this, SLOT(setSystemType(UASInterface*,uint)));
connect(active, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(receiveTextMessage(int,int,int,QString)));
// Update all values once
nameLabel->setText(mav->getUASName());
......@@ -81,6 +83,7 @@ void QGCToolBar::createCustomWidgets()
stateLabel = new QLabel("------", this);
wpLabel = new QLabel("---", this);
distlabel = new QLabel("--- ---- m", this);
messageLabel = new QLabel("No system messages.", this);
//symbolButton->setIcon(":");
symbolButton->setStyleSheet("QWidget { background-color: #050508; color: #DDDDDF; background-clip: border; } QToolButton { font-weight: bold; font-size: 12px; border: 0px solid #999999; border-radius: 5px; min-width:22px; max-width: 22px; min-height: 22px; max-height: 22px; padding: 0px; margin: 0px; background-color: none; }");
addWidget(symbolButton);
......@@ -89,6 +92,7 @@ void QGCToolBar::createCustomWidgets()
addWidget(stateLabel);
addWidget(wpLabel);
addWidget(distlabel);
addWidget(messageLabel);
toggleLoggingAction = new QAction(QIcon(":"), "Start Logging", this);
logReplayAction = new QAction(QIcon(":"), "Start Replay", this);
......@@ -154,6 +158,14 @@ void QGCToolBar::setSystemType(UASInterface* uas, unsigned int systemType)
}
}
void QGCToolBar::receiveTextMessage(int uasid, int componentid, int severity, QString text)
{
Q_UNUSED(uasid);
Q_UNUSED(componentid);
Q_UNUSED(severity);
messageLabel->setText(text);
}
QGCToolBar::~QGCToolBar()
{
delete toggleLoggingAction;
......
......@@ -50,6 +50,8 @@ public slots:
void updateName(const QString& name);
/** @brief Set the MAV system type */
void setSystemType(UASInterface* uas, unsigned int systemType);
/** @brief Received system text message */
void receiveTextMessage(int uasid, int componentid, int severity, QString text);
protected:
void createCustomWidgets();
......@@ -63,7 +65,7 @@ protected:
QLabel* stateLabel;
QLabel* wpLabel;
QLabel* distlabel;
QLabel* messageLabel;
};
#endif // QGCTOOLBAR_H
......@@ -602,6 +602,8 @@ void UASView::refresh()
m_ui->heartbeatIcon->setStyleSheet(colorstyle.arg(warnColor.name()));
QString style = QString("QGroupBox { border-radius: 12px; padding: 0px; margin: 0px; border: 2px solid %1; background-color: %2; }").arg(borderColor, warnColor.name());
m_ui->uasViewFrame->setStyleSheet(style);
refreshTimer->setInterval(errorUpdateInterval);
}
iconIsRed = !iconIsRed;
} else {
......@@ -609,10 +611,11 @@ void UASView::refresh()
{
// Fade heartbeat icon
// Make color darker
heartbeatColor = heartbeatColor.darker(150);
heartbeatColor = heartbeatColor.darker(210);
//m_ui->heartbeatIcon->setAutoFillBackground(true);
m_ui->heartbeatIcon->setStyleSheet(colorstyle.arg(heartbeatColor.name()));
refreshTimer->setInterval(updateInterval);
}
}
//setUpdatesEnabled(true);
......
......@@ -122,7 +122,8 @@ protected:
QAction* selectAction;
QAction* selectAirframeAction;
QAction* setBatterySpecsAction;
static const int updateInterval = 700;
static const int updateInterval = 800;
static const int errorUpdateInterval = 200;
bool lowPowerModeEnabled; ///< Low power mode reduces update rates
......
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