diff --git a/flightgear/connector_flightgear_uav.xml b/flightgear/connector_flightgear_uav.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0513e1cd96dd4a9954d0821d1d5d459abd337910
--- /dev/null
+++ b/flightgear/connector_flightgear_uav.xml
@@ -0,0 +1,161 @@
+
+
+
+
+
+ newline
+ ,
+
+
+ pitch
+ float
+ %+1.3f
+ /autopilot/settings/target-pitch-deg
+
+
+
+ roll
+ float
+ %+1.3f
+ /autopilot/settings/target-roll-deg
+
+
+
+ throttle
+ float
+ %+1.3f
+ /controls/engines/engine/throttle
+
+
+
+ lat
+ float
+ %+1.8f
+ /sim/view/target/latitude-deg
+
+
+
+ lon
+ float
+ %+1.8f
+ /sim/view/target/longitude-deg
+
+
+
+ alt
+ float
+ %+1.4f
+ /sim/view/target/alt
+
+
+
+
+
+
diff --git a/src/comm/QGCFlightGearLink.cc b/src/comm/QGCFlightGearLink.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3a4817935f41c26339065bbb8bd9bf4caf45cb74
--- /dev/null
+++ b/src/comm/QGCFlightGearLink.cc
@@ -0,0 +1,301 @@
+/*=====================================================================
+
+QGroundControl Open Source Ground Control Station
+
+(c) 2009 - 2011 QGROUNDCONTROL PROJECT
+
+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 .
+
+======================================================================*/
+
+/**
+ * @file
+ * @brief Definition of UDP connection (server) for unmanned vehicles
+ * @author Lorenz Meier
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "QGCFlightGearLink.h"
+#include "LinkManager.h"
+#include "QGC.h"
+#include
+//#include
+
+QGCFlightGearLink::QGCFlightGearLink(QHostAddress host, quint16 port)
+{
+ this->host = host;
+ this->port = port;
+ this->connectState = false;
+ // Set unique ID and add link to the list of links
+ this->name = tr("FlightGear Link (port:%1)").arg(5401);
+ LinkManager::instance()->add(this);
+}
+
+QGCFlightGearLink::~QGCFlightGearLink()
+{
+ disconnect();
+}
+
+/**
+ * @brief Runs the thread
+ *
+ **/
+void QGCFlightGearLink::run()
+{
+// forever
+// {
+// QGC::SLEEP::msleep(5000);
+// }
+ exec();
+}
+
+void QGCFlightGearLink::setPort(int port)
+{
+ this->port = port;
+ disconnect();
+ connect();
+}
+
+/**
+ * @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 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(":");
+ }
+ }
+ else
+ {
+ QHostInfo info = QHostInfo::fromName(host);
+ if (info.error() == QHostInfo::NoError)
+ {
+ // Add host
+ currentHost = info.addresses().first();
+ }
+ }
+}
+
+void QGCFlightGearLink::writeBytes(const char* data, qint64 size)
+{
+ // Broadcast to all connected systems
+ for (int h = 0; h < hosts.size(); h++)
+ {
+ quint16 currentPort = ports.at(h);
+//#define QGCFlightGearLink_DEBUG
+#ifdef QGCFlightGearLink_DEBUG
+ QString bytes;
+ QString ascii;
+ for (int i=0; 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);
+
+// // Echo data for debugging purposes
+// std::cerr << __FILE__ << __LINE__ << "Received datagram:" << std::endl;
+// int i;
+// for (i=0; iinsert(sender, senderPort);
+ }
+ else
+ {
+ int index = hosts.indexOf(sender);
+ ports.replace(index, senderPort);
+ }
+
+}
+
+
+/**
+ * @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::disconnect()
+{
+ delete socket;
+ socket = NULL;
+
+ connectState = false;
+
+ emit disconnected();
+ emit connected(false);
+ return !connectState;
+}
+
+/**
+ * @brief Connect the connection.
+ *
+ * @return True if connection has been established, false if connection couldn't be established.
+ **/
+bool QGCFlightGearLink::connect()
+{
+ 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 connected(connectState);
+ if (connectState) {
+ emit connected();
+ 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);
+}
diff --git a/src/comm/QGCFlightGearLink.h b/src/comm/QGCFlightGearLink.h
new file mode 100644
index 0000000000000000000000000000000000000000..2e2bdb94806b6045d914f464dfb4147c31106cd9
--- /dev/null
+++ b/src/comm/QGCFlightGearLink.h
@@ -0,0 +1,112 @@
+/*=====================================================================
+
+QGroundControl Open Source Ground Control Station
+
+(c) 2009 - 2011 QGROUNDCONTROL PROJECT
+
+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 .
+
+======================================================================*/
+
+/**
+ * @file
+ * @brief UDP connection (server) for unmanned vehicles
+ * @author Lorenz Meier
+ *
+ */
+
+#ifndef QGCFLIGHTGEARLINK_H
+#define QGCFLIGHTGEARLINK_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+class QGCFlightGearLink : public QThread
+{
+ Q_OBJECT
+ //Q_INTERFACES(QGCFlightGearLinkInterface:LinkInterface)
+
+public:
+ QGCFlightGearLink(QHostAddress host = QHostAddress::Any, quint16 port = 5401);
+ //QGCFlightGearLink(QHostAddress host = "239.255.76.67", quint16 port = 7667);
+ ~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 addHost(const QString& host);
+ /** @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 connect();
+ bool disconnect();
+
+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;
+
+ void setName(QString name);
+
+signals:
+ // Signals are defined by LinkInterface
+
+};
+
+#endif // QGCFLIGHTGEARLINK_H