1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

GCS/HITL Simulation with FlightGear, only tested on Win7, see http://wiki.openpilot.org/HITL_Simulation for more details and video.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@686 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
vassilis 2010-05-30 02:12:53 +00:00 committed by vassilis
parent 6414887dcc
commit c2a30176de
22 changed files with 1924 additions and 5 deletions

View File

@ -0,0 +1,12 @@
<plugin name="HITL" version="1.0.0" compatVersion="1.0.0">
<vendor>The OpenPilot Project</vendor>
<copyright>(C) 2010 OpenPilot Project</copyright>
<license>The GNU Public License (GPL) Version 3</license>
<description>Hardware In The Loop Simulation</description>
<url>http://www.openpilot.org</url>
<dependencyList>
<dependency name="Core" version="1.0.0"/>
<dependency name="UAVObjects" version="0.0.1"/>
<dependency name="UAVTalk" version="0.0.1"/>
</dependencyList>
</plugin>

View File

@ -0,0 +1,295 @@
/**
******************************************************************************
*
* @file flightgearbridge.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "flightgearbridge.h"
#include "extensionsystem/pluginmanager.h"
FlightGearBridge::FlightGearBridge()
{
// Init fields
fgHost = QHostAddress("127.0.0.1");
inPort = 5500;
outPort = 5501;
updatePeriod = 50;
fgTimeout = 2000;
autopilotConnectionStatus = false;
fgConnectionStatus = false;
// Get required UAVObjects
ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager* objManager = pm->getObject<UAVObjectManager>();
actDesired = ActuatorDesired::GetInstance(objManager);
altActual = AltitudeActual::GetInstance(objManager);
attActual = AttitudeActual::GetInstance(objManager);
gps = GpsObject::GetInstance(objManager);
telStats = GCSTelemetryStats::GetInstance(objManager);
// Listen to autopilot connection events
// NOTE: Disabled due to linker errors, when fixed uncomment next three lines and comment out fourth
TelemetryManager* telMngr = pm->getObject<TelemetryManager>();
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
//connect(telStats, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(telStatsUpdated(UAVObject*)));
// If already connect setup autopilot
GCSTelemetryStats::DataFields stats = telStats->getData();
if ( stats.Status == GCSTelemetryStats::STATUS_CONNECTED )
{
onAutopilotConnect();
}
// Setup local ports
inSocket = new QUdpSocket(this);
outSocket = new QUdpSocket(this);
inSocket->bind(QHostAddress::Any, inPort);
connect(inSocket, SIGNAL(readyRead()), this, SLOT(receiveUpdate()));
// Setup transmit timer
txTimer = new QTimer(this);
connect(txTimer, SIGNAL(timeout()), this, SLOT(transmitUpdate()));
txTimer->setInterval(updatePeriod);
txTimer->start();
// Setup FG connection timer
fgTimer = new QTimer(this);
connect(fgTimer, SIGNAL(timeout()), this, SLOT(onFGConnectionTimeout()));
fgTimer->setInterval(fgTimeout);
fgTimer->start();
}
FlightGearBridge::~FlightGearBridge()
{
delete inSocket;
delete outSocket;
delete txTimer;
delete fgTimer;
}
bool FlightGearBridge::isAutopilotConnected()
{
return autopilotConnectionStatus;
}
bool FlightGearBridge::isFGConnected()
{
return fgConnectionStatus;
}
void FlightGearBridge::transmitUpdate()
{
// Read ActuatorDesired from autopilot
ActuatorDesired::DataFields actData = actDesired->getData();
float ailerons = actData.Roll;
float elevator = -actData.Pitch;
float rudder = actData.Yaw;
float throttle = actData.Throttle;
// Send update to FlightGear
QString cmd;
cmd = QString("%1,%2,%3,%4\n")
.arg(ailerons)
.arg(elevator)
.arg(rudder)
.arg(throttle);
QByteArray data = cmd.toAscii();
outSocket->writeDatagram(data, fgHost, outPort);
}
void FlightGearBridge::receiveUpdate()
{
// Update connection timer and status
fgTimer->setInterval(fgTimeout);
fgTimer->stop();
fgTimer->start();
if ( !fgConnectionStatus )
{
fgConnectionStatus = true;
emit fgConnected();
}
// Process data
while ( inSocket->bytesAvailable() > 0 )
{
// Receive datagram
QByteArray datagram;
datagram.resize(inSocket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
inSocket->readDatagram(datagram.data(), datagram.size(),
&sender, &senderPort);
QString datastr(datagram);
// Process incomming data
processUpdate(datastr);
}
}
void FlightGearBridge::setupObjects()
{
setupInputObject(actDesired, 50);
setupOutputObject(altActual, 250);
setupOutputObject(attActual, 50);
setupOutputObject(gps, 250);
}
void FlightGearBridge::setupInputObject(UAVObject* obj, int updatePeriod)
{
UAVObject::Metadata mdata;
mdata = obj->getDefaultMetadata();
mdata.flightAccess = UAVObject::ACCESS_READWRITE;
mdata.gcsAccess = UAVObject::ACCESS_READWRITE;
mdata.flightTelemetryAcked = false;
mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
mdata.flightTelemetryUpdatePeriod = updatePeriod;
mdata.gcsTelemetryUpdateMode = UAVObject::UPDATEMODE_MANUAL;
obj->setMetadata(mdata);
}
void FlightGearBridge::setupOutputObject(UAVObject* obj, int updatePeriod)
{
UAVObject::Metadata mdata;
mdata = obj->getDefaultMetadata();
mdata.flightAccess = UAVObject::ACCESS_READONLY;
mdata.gcsAccess = UAVObject::ACCESS_READWRITE;
mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_NEVER;
mdata.gcsTelemetryAcked = false;
mdata.gcsTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
mdata.gcsTelemetryUpdatePeriod = updatePeriod;
obj->setMetadata(mdata);
}
void FlightGearBridge::onAutopilotConnect()
{
autopilotConnectionStatus = true;
setupObjects();
emit autopilotConnected();
}
void FlightGearBridge::onAutopilotDisconnect()
{
autopilotConnectionStatus = false;
emit autopilotDisconnected();
}
void FlightGearBridge::onFGConnectionTimeout()
{
if ( fgConnectionStatus )
{
fgConnectionStatus = false;
emit fgDisconnected();
}
}
void FlightGearBridge::processUpdate(QString& data)
{
// Split
QStringList fields = data.split(",");
// Get xRate (deg/s)
float xRate = fields[0].toFloat() * 180.0/M_PI;
// Get yRate (deg/s)
float yRate = fields[1].toFloat() * 180.0/M_PI;
// Get zRate (deg/s)
float zRate = fields[2].toFloat() * 180.0/M_PI;
// Get xAccel (m/s^2)
float xAccel = fields[3].toFloat() * FT2M;
// Get yAccel (m/s^2)
float yAccel = fields[4].toFloat() * FT2M;
// Get xAccel (m/s^2)
float zAccel = fields[5].toFloat() * FT2M;
// Get pitch (deg)
float pitch = fields[6].toFloat();
// Get pitchRate (deg/s)
float pitchRate = fields[7].toFloat();
// Get roll (deg)
float roll = fields[8].toFloat();
// Get rollRate (deg/s)
float rollRate = fields[9].toFloat();
// Get yaw (deg)
float yaw = fields[10].toFloat();
// Get yawRate (deg/s)
float yawRate = fields[11].toFloat();
// Get latitude (deg)
float latitude = fields[12].toFloat();
// Get longitude (deg)
float longitude = fields[13].toFloat();
// Get heading (deg)
float heading = fields[14].toFloat();
// Get altitude (m)
float altitude = fields[15].toFloat() * FT2M;
// Get altitudeAGL (m)
float altitudeAGL = fields[16].toFloat() * FT2M;
// Get groundspeed (m/s)
float groundspeed = fields[17].toFloat() * KT2MPS;
// Get airspeed (m/s)
float airspeed = fields[18].toFloat() * KT2MPS;
// Get temperature (degC)
float temperature = fields[19].toFloat();
// Get pressure (kpa)
float pressure = fields[20].toFloat() * INHG2KPA;
// Update AltitudeActual object
AltitudeActual::DataFields altActualData;
altActualData.Altitude = altitudeAGL;
altActualData.Temperature = temperature;
altActualData.Pressure = pressure;
altActual->setData(altActualData);
// Update attActual object
AttitudeActual::DataFields attActualData;
attActualData.Roll = roll;
attActualData.Pitch = pitch;
attActualData.Yaw = yaw;
attActualData.q1 = 0;
attActualData.q2 = 0;
attActualData.q3 = 0;
attActualData.q4 = 0;
attActualData.seq = 0;
attActual->setData(attActualData);
// Update gps objects
GpsObject::DataFields gpsData;
gpsData.Altitude = altitude;
gpsData.Heading = heading;
gpsData.GroundSpeed = groundspeed;
gpsData.Latitude = latitude;
gpsData.Longitude = longitude;
gpsData.Satellites = 10;
gpsData.Updates = 0;
gps->setData(gpsData);
}
void FlightGearBridge::telStatsUpdated(UAVObject* obj)
{
GCSTelemetryStats::DataFields stats = telStats->getData();
if ( !autopilotConnectionStatus && stats.Status == GCSTelemetryStats::STATUS_CONNECTED )
{
onAutopilotConnect();
}
else if ( autopilotConnectionStatus && stats.Status != GCSTelemetryStats::STATUS_CONNECTED )
{
onAutopilotDisconnect();
}
}

View File

@ -0,0 +1,96 @@
/**
******************************************************************************
*
* @file flightgearbridge.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef FLIGHTGEARBRIDGE_H
#define FLIGHTGEARBRIDGE_H
#include <QObject>
#include <QUdpSocket>
#include <QTimer>
#include <math.h>
#include "uavtalk/telemetrymanager.h"
#include "uavobjects/uavobjectmanager.h"
#include "uavobjects/actuatordesired.h"
#include "uavobjects/altitudeactual.h"
#include "uavobjects/attitudeactual.h"
#include "uavobjects/gpsobject.h"
#include "uavobjects/gcstelemetrystats.h"
class FlightGearBridge: public QObject
{
Q_OBJECT
public:
FlightGearBridge();
~FlightGearBridge();
bool isAutopilotConnected();
bool isFGConnected();
signals:
void autopilotConnected();
void autopilotDisconnected();
void fgConnected();
void fgDisconnected();
private slots:
void transmitUpdate();
void receiveUpdate();
void onAutopilotConnect();
void onAutopilotDisconnect();
void onFGConnectionTimeout();
void telStatsUpdated(UAVObject* obj);
private:
static const float FT2M = 0.3048;
static const float KT2MPS = 0.514444444;
static const float INHG2KPA = 3.386;
QUdpSocket* inSocket;
QUdpSocket* outSocket;
ActuatorDesired* actDesired;
AltitudeActual* altActual;
AttitudeActual* attActual;
GpsObject* gps;
GCSTelemetryStats* telStats;
QHostAddress fgHost;
int inPort;
int outPort;
int updatePeriod;
QTimer* txTimer;
QTimer* fgTimer;
bool autopilotConnectionStatus;
bool fgConnectionStatus;
int fgTimeout;
void processUpdate(QString& data);
void setupOutputObject(UAVObject* obj, int updatePeriod);
void setupInputObject(UAVObject* obj, int updatePeriod);
void setupObjects();
};
#endif // FLIGHTGEARBRIDGE_H

View File

@ -0,0 +1,49 @@
/**
******************************************************************************
*
* @file hitl.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "hitl.h"
#include "hitlwidget.h"
#include "hitlconfiguration.h"
HITL::HITL(QString classId, HITLWidget *widget, QWidget *parent) :
IUAVGadget(classId, parent),
m_widget(widget)
{
}
HITL::~HITL()
{
}
void HITL::loadConfiguration(IUAVGadgetConfiguration* config)
{
HITLConfiguration *m = qobject_cast<HITLConfiguration*>(config);
m_widget->setFGPathBin( m->fgPathBin() );
m_widget->setFGPathData( m->fgPathData() );
m_widget->setFGManualControl( m->fgManualControl() );
}

View File

@ -0,0 +1,56 @@
/**
******************************************************************************
*
* @file hitl.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef HITL_H
#define HITL_H
#include <coreplugin/iuavgadget.h>
#include "hitlwidget.h"
class IUAVGadget;
class QWidget;
class QString;
class HITLWidget;
using namespace Core;
class HITL : public Core::IUAVGadget
{
Q_OBJECT
public:
HITL(QString classId, HITLWidget *widget, QWidget *parent = 0);
~HITL();
QWidget *widget() { return m_widget; }
void loadConfiguration(IUAVGadgetConfiguration* config);
private:
HITLWidget *m_widget;
};
#endif // HITL_H

View File

@ -0,0 +1,23 @@
TEMPLATE = lib
TARGET = HITL
QT += network
include(../../openpilotgcsplugin.pri)
include(hitl_dependencies.pri)
HEADERS += hitlplugin.h \
hitlwidget.h \
hitloptionspage.h \
hitlfactory.h \
hitlconfiguration.h \
hitl.h \
flightgearbridge.h
SOURCES += hitlplugin.cpp \
hitlwidget.cpp \
hitloptionspage.cpp \
hitlfactory.cpp \
hitlconfiguration.cpp \
hitl.cpp \
flightgearbridge.cpp
OTHER_FILES += HITL.pluginspec
FORMS += hitloptionspage.ui \
hitlwidget.ui
RESOURCES += hitlresources.qrc

View File

@ -0,0 +1,4 @@
include(../../plugins/uavobjects/uavobjects.pri)
include(../../plugins/uavtalk/uavtalk.pri)
include(../../plugins/coreplugin/coreplugin.pri)
include(../../libs/utils/utils.pri)

View File

@ -0,0 +1,67 @@
/**
******************************************************************************
*
* @file hitlconfiguration.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "hitlconfiguration.h"
#include <QtCore/QDataStream>
HITLConfiguration::HITLConfiguration(QString classId, const QByteArray &state, QObject *parent) :
IUAVGadgetConfiguration(classId, parent),
m_fgPathBin(""), m_fgPathData(""), m_fgManualControl(false)
{
if (state.count() > 0) {
QDataStream stream(state);
QString fgPathBin;
QString fgPathData;
bool fgManualControl;
stream >> fgPathBin;
m_fgPathBin = fgPathBin;
stream >> fgPathData;
m_fgPathData = fgPathData;
stream >> fgManualControl;
m_fgManualControl = fgManualControl;
}
}
IUAVGadgetConfiguration *HITLConfiguration::clone()
{
HITLConfiguration *m = new HITLConfiguration(this->classId());
m->m_fgPathBin = m_fgPathBin;
m->m_fgPathData = m_fgPathData;
m->m_fgManualControl = m_fgManualControl;
return m;
}
QByteArray HITLConfiguration::saveState() const
{
QByteArray bytes;
QDataStream stream(&bytes, QIODevice::WriteOnly);
stream << m_fgPathBin;
stream << m_fgPathData;
stream << m_fgManualControl;
return bytes;
}

View File

@ -0,0 +1,68 @@
/**
******************************************************************************
*
* @file hitlconfiguration.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef HITLCONFIGURATION_H
#define HITLCONFIGURATION_H
#include <coreplugin/iuavgadgetconfiguration.h>
#include <QtGui/QColor>
#include <QString>
using namespace Core;
class HITLConfiguration : public IUAVGadgetConfiguration
{
Q_OBJECT
Q_PROPERTY(QString m_fgPathBin READ fgPathBin WRITE setFGPathBin)
Q_PROPERTY(QString m_fgPathData READ fgPathData WRITE setFGPathData)
Q_PROPERTY(bool m_fgManualControl READ fgManualControl WRITE setFGManualControl)
public:
explicit HITLConfiguration(QString classId, const QByteArray &state = 0, QObject *parent = 0);
QByteArray saveState() const;
IUAVGadgetConfiguration *clone();
QString fgPathBin() const { return m_fgPathBin; }
QString fgPathData() const { return m_fgPathData; }
bool fgManualControl() const { return m_fgManualControl; }
signals:
public slots:
void setFGPathBin(QString fgPath) { m_fgPathBin = fgPath; }
void setFGPathData(QString fgPath) { m_fgPathData = fgPath; }
void setFGManualControl(bool val) { m_fgManualControl = val; }
private:
QString m_fgPathBin;
QString m_fgPathData;
bool m_fgManualControl;
};
#endif // HITLCONFIGURATION_H

View File

@ -0,0 +1,58 @@
/**
******************************************************************************
*
* @file hitlfactory.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "hitlfactory.h"
#include "hitlwidget.h"
#include "hitl.h"
#include "hitlconfiguration.h"
#include "hitloptionspage.h"
#include <coreplugin/iuavgadget.h>
HITLFactory::HITLFactory(QObject *parent) :
IUAVGadgetFactory(QString("HITL"), tr("HITL Simulation"), parent)
{
}
HITLFactory::~HITLFactory()
{
}
Core::IUAVGadget* HITLFactory::createGadget(QWidget *parent)
{
HITLWidget* gadgetWidget = new HITLWidget(parent);
return new HITL(QString("HITL"), gadgetWidget, parent);
}
IUAVGadgetConfiguration *HITLFactory::createConfiguration(const QByteArray &state)
{
return new HITLConfiguration(QString("HITL"), state);
}
IOptionsPage *HITLFactory::createOptionsPage(IUAVGadgetConfiguration *config)
{
return new HITLOptionsPage(qobject_cast<HITLConfiguration*>(config));
}

View File

@ -0,0 +1,52 @@
/**
******************************************************************************
*
* @file hitlfactory.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef HITLFACTORY_H
#define HITLFACTORY_H
#include <coreplugin/iuavgadgetfactory.h>
namespace Core {
class IUAVGadget;
class IUAVGadgetFactory;
}
using namespace Core;
class HITLFactory : public Core::IUAVGadgetFactory
{
Q_OBJECT
public:
HITLFactory(QObject *parent = 0);
~HITLFactory();
Core::IUAVGadget *createGadget(QWidget *parent);
IUAVGadgetConfiguration *createConfiguration(const QByteArray &state);
IOptionsPage *createOptionsPage(IUAVGadgetConfiguration *config);
};
#endif // HITLFACTORY_H

View File

@ -0,0 +1,96 @@
/**
******************************************************************************
*
* @file hitloptionspage.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "hitloptionspage.h"
#include "hitlconfiguration.h"
#include "ui_hitloptionspage.h"
#include <QFileDialog>
#include <QtAlgorithms>
#include <QStringList>
HITLOptionsPage::HITLOptionsPage(HITLConfiguration *config, QObject *parent) :
IOptionsPage(parent),
m_config(config)
{
}
QWidget *HITLOptionsPage::createPage(QWidget *parent)
{
// Create page
m_optionsPage = new Ui::HITLOptionsPage();
QWidget* optionsPageWidget = new QWidget;
m_optionsPage->setupUi(optionsPageWidget);
connect(m_optionsPage->loadFileBin, SIGNAL(clicked()), this, SLOT(onLoadFileBinClicked()));
connect(m_optionsPage->loadFileData, SIGNAL(clicked()), this, SLOT(onLoadFileDataClicked()));
// Restore the contents from the settings:
m_optionsPage->fgPathBin->setText(m_config->fgPathBin());
m_optionsPage->fgPathData->setText(m_config->fgPathData());
m_optionsPage->fgManualControl->setChecked(m_config->fgManualControl());
return optionsPageWidget;
}
void HITLOptionsPage::apply()
{
m_config->setFGPathBin( m_optionsPage->fgPathBin->text());
m_config->setFGPathData( m_optionsPage->fgPathData->text());
m_config->setFGManualControl( m_optionsPage->fgManualControl->isChecked());
}
void HITLOptionsPage::finish()
{
disconnect(this);
delete m_optionsPage;
}
void HITLOptionsPage::onLoadFileBinClicked()
{
QFileDialog::Options options;
QString selectedFilter;
QString fileName = QFileDialog::getOpenFileName(qobject_cast<QWidget*>(this),
tr("QFileDialog::getOpenFileName()"),
m_optionsPage->fgPathBin->text(),
tr("All Files (*)"),
&selectedFilter,
options);
if (!fileName.isEmpty()) m_optionsPage->fgPathBin->setText(fileName);
}
void HITLOptionsPage::onLoadFileDataClicked()
{
QFileDialog::Options options;
QString selectedFilter;
QString fileName = QFileDialog::getExistingDirectory(qobject_cast<QWidget*>(this),
tr("Open Directory"),
m_optionsPage->fgPathData->text(),
QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks);
if (!fileName.isEmpty()) m_optionsPage->fgPathData->setText(fileName);
}

View File

@ -0,0 +1,67 @@
/**
******************************************************************************
*
* @file hitloptionspage.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef HITLOPTIONSPAGE_H
#define HITLOPTIONSPAGE_H
#include "coreplugin/dialogs/ioptionspage.h"
namespace Core {
class IUAVGadgetConfiguration;
}
class HITLConfiguration;
using namespace Core;
namespace Ui {
class HITLOptionsPage;
}
class HITLOptionsPage : public IOptionsPage
{
Q_OBJECT
public:
explicit HITLOptionsPage(HITLConfiguration *config, QObject *parent = 0);
QWidget *createPage(QWidget *parent);
void apply();
void finish();
signals:
private slots:
void onLoadFileBinClicked();
void onLoadFileDataClicked();
private:
HITLConfiguration* m_config;
Ui::HITLOptionsPage* m_optionsPage;
};
#endif // HITLOPTIONSPAGE_H

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>HITLOptionsPage</class>
<widget class="QWidget" name="HITLOptionsPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>675</width>
<height>300</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>-1</x>
<y>-1</y>
<width>481</width>
<height>339</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0,0">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0">
<property name="spacing">
<number>10</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>FlightGear Executable</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="fgPathBin">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="loadFileBin">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>FlightGear Data Directory</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="fgPathData"/>
</item>
<item>
<widget class="QPushButton" name="loadFileData">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<widget class="QCheckBox" name="fgManualControl">
<property name="text">
<string>Manual aircraft control (can be used when hardware is not available)</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,63 @@
/**
******************************************************************************
*
* @file mapplugin.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "hitlplugin.h"
#include "hitlfactory.h"
#include <QtPlugin>
#include <QStringList>
#include <extensionsystem/pluginmanager.h>
HITLPlugin::HITLPlugin()
{
// Do nothing
}
HITLPlugin::~HITLPlugin()
{
// Do nothing
}
bool HITLPlugin::initialize(const QStringList& args, QString *errMsg)
{
Q_UNUSED(args);
Q_UNUSED(errMsg);
mf = new HITLFactory(this);
addAutoReleasedObject(mf);
return true;
}
void HITLPlugin::extensionsInitialized()
{
// Do nothing
}
void HITLPlugin::shutdown()
{
// Do nothing
}
Q_EXPORT_PLUGIN(HITLPlugin)

View File

@ -0,0 +1,47 @@
/**
******************************************************************************
*
* @file browserplugin.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef HITLPLUGIN_H
#define HITLPLUGIN_H
#include <extensionsystem/iplugin.h>
class HITLFactory;
class HITLPlugin : public ExtensionSystem::IPlugin
{
public:
HITLPlugin();
~HITLPlugin();
void extensionsInitialized();
bool initialize(const QStringList & arguments, QString * errorString);
void shutdown();
private:
HITLFactory *mf;
};
#endif /* HITLPLUGIN_H */

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/flightgear/genericprotocol">
<file>opfgprotocol.xml</file>
</qresource>
</RCC>

View File

@ -0,0 +1,209 @@
/**
******************************************************************************
*
* @file hitlwidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "hitlwidget.h"
#include "ui_hitlwidget.h"
#include "qxtlogger.h"
#include <QDebug>
#include "uavobjects/uavobjectmanager.h"
#include <QFile>
#include <QDir>
HITLWidget::HITLWidget(QWidget *parent) : QWidget(parent)
{
// Note: Only tested on windows 7
#if defined(Q_WS_WIN)
cmdShell = QString("c:/windows/system32/cmd.exe");
#else
cmdShell = QString("bash");
#endif
fgProcess = NULL;
widget = new Ui_HITLWidget();
widget->setupUi(this);
connect(widget->startButton, SIGNAL(clicked()), this, SLOT(startButtonClicked()));
connect(widget->stopButton, SIGNAL(clicked()), this, SLOT(stopButtonClicked()));
}
HITLWidget::~HITLWidget()
{
delete widget;
}
void HITLWidget::startButtonClicked()
{
// Stop running process if one is active
if (fgProcess != NULL)
{
stopButtonClicked();
}
// Copy FlightGear generic protocol configuration file to the FG protocol directory
// NOTE: Not working on Windows 7, if FG is installed in the "Program Files",
// likelly due to permissions. The file should be manually copied to data/Protocol/opfgprotocol.xml
QFile xmlFile(":/flightgear/genericprotocol/opfgprotocol.xml");
xmlFile.open(QIODevice::ReadOnly | QIODevice::Text);
QString xml = xmlFile.readAll();
xmlFile.close();
QFile xmlFileOut(fgPathData + "/Protocol/opfgprotocol.xml");
xmlFileOut.open(QIODevice::WriteOnly | QIODevice::Text);
xmlFileOut.write(xml.toAscii());
xmlFileOut.close();
// Setup process
widget->textBrowser->append(QString("Starting FlightGear ...\n"));
qxtLog->info("HITL: Starting FlightGear");
fgProcess = new QProcess();
fgProcess->setReadChannelMode(QProcess::MergedChannels);
connect(fgProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(processReadyRead()));
// Start shell (Note: Could not start FG directly on Windows, only through terminal!)
fgProcess->start(cmdShell);
if (fgProcess->waitForStarted() == false)
{
widget->textBrowser->append("Error:" + fgProcess->errorString());
}
// Setup arguments
// Note: The input generic protocol is set to update at a much higher rate than the actual updates are sent by the GCS.
// If this is not done then a lag will be introduced by FlightGear, likelly because the receive socket buffer builds up during startup.
QString args("--fg-root=\"" + fgPathData + "\" --timeofday=dusk --httpd=5400 --enable-hud --in-air --altitude=2000 --vc=100 --generic=socket,out,50,localhost,5500,udp,opfgprotocol");
if ( !fgManualControl )
{
args.append(" --generic=socket,in,400,localhost,5501,udp,opfgprotocol");
}
// Start FlightGear
QString cmd;
cmd = "\"" + fgPathBin + "\" " + args + "\n";
fgProcess->write(cmd.toAscii());
// Start bridge
qxtLog->info("HITL: Starting bridge, initializing FlighGear and Autopilot connections");
fgBridge = new FlightGearBridge();
connect(fgBridge, SIGNAL(autopilotConnected()), this, SLOT(onAutopilotConnect()));
connect(fgBridge, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect()));
connect(fgBridge, SIGNAL(fgConnected()), this, SLOT(onFGConnect()));
connect(fgBridge, SIGNAL(fgDisconnected()), this, SLOT(onFGDisconnect()));
// Initialize connection status
if ( fgBridge->isAutopilotConnected() )
{
onAutopilotConnect();
}
else
{
onAutopilotDisconnect();
}
if ( fgBridge->isFGConnected() )
{
onFGConnect();
}
else
{
onFGDisconnect();
}
}
void HITLWidget::stopButtonClicked()
{
// NOTE: Does not currently work, may need to send control+c to through the terminal
if (fgProcess != NULL)
{
fgProcess->disconnect(this);
fgProcess->kill();
delete fgProcess;
fgBridge->disconnect(this);
delete fgBridge;
fgProcess = NULL;
}
}
void HITLWidget::setFGPathBin(QString fgPath)
{
this->fgPathBin = fgPath;
}
void HITLWidget::setFGPathData(QString fgPath)
{
this->fgPathData = fgPath;
}
void HITLWidget::setFGManualControl(bool val)
{
this->fgManualControl = val;
}
void HITLWidget::processReadyRead()
{
QByteArray bytes = fgProcess->readAllStandardOutput();
QString str(bytes);
if ( !str.contains("Error reading data") ) // ignore error
{
widget->textBrowser->append(str);
}
}
void HITLWidget::onAutopilotConnect()
{
QPalette pal(widget->apLabel->palette());
pal.setColor(QPalette::Window, Qt::green);
widget->apLabel->setPalette(pal);
widget->apLabel->setAutoFillBackground(true);
widget->apLabel->setText("AutoPilot Connected");
qxtLog->info("HITL: Autopilot connected, initializing for HITL simulation");
}
void HITLWidget::onAutopilotDisconnect()
{
QPalette pal(widget->apLabel->palette());
pal.setColor(QPalette::Window, Qt::red);
widget->apLabel->setPalette(pal);
widget->apLabel->setAutoFillBackground(true);
widget->apLabel->setText("AutoPilot Disconnected");
qxtLog->info("HITL: Autopilot disconnected");
}
void HITLWidget::onFGConnect()
{
QPalette pal(widget->fgLabel->palette());
pal.setColor(QPalette::Window, Qt::green);
widget->fgLabel->setPalette(pal);
widget->fgLabel->setAutoFillBackground(true);
widget->fgLabel->setText("FlightGear Connected");
qxtLog->info("HITL: FlighGear connected");
}
void HITLWidget::onFGDisconnect()
{
QPalette pal(widget->fgLabel->palette());
pal.setColor(QPalette::Window, Qt::red);
widget->fgLabel->setPalette(pal);
widget->fgLabel->setAutoFillBackground(true);
widget->fgLabel->setText("FlightGear Disconnected");
qxtLog->info("HITL: FlighGear disconnected");
}

View File

@ -0,0 +1,70 @@
/**
******************************************************************************
*
* @file hitlwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup hitl
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef HITLWIDGET_H
#define HITLWIDGET_H
#include <QtGui/QWidget>
#include <QProcess>
#include "flightgearbridge.h"
class Ui_HITLWidget;
class HITLWidget : public QWidget
{
Q_OBJECT
public:
HITLWidget(QWidget *parent = 0);
~HITLWidget();
void setFGPathBin(QString fgPath);
void setFGPathData(QString fgPath);
void setFGManualControl(bool val);
public slots:
private slots:
void startButtonClicked();
void stopButtonClicked();
void processReadyRead();
void onAutopilotConnect();
void onAutopilotDisconnect();
void onFGConnect();
void onFGDisconnect();
private:
Ui_HITLWidget* widget;
FlightGearBridge* fgBridge;
QProcess* fgProcess;
QString fgPathBin;
QString fgPathData;
bool fgManualControl;
QString cmdShell;
};
#endif /* HITLWIDGET_H */

View File

@ -0,0 +1,210 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>HITLWidget</class>
<widget class="QWidget" name="HITLWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>786</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="startButton">
<property name="toolTip">
<string>Request update</string>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="stopButton">
<property name="toolTip">
<string>Send update</string>
</property>
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="apLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="text">
<string>AutoPilot Disconnected</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="fgLabel">
<property name="text">
<string>FlighGear Disconnected</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QTextBrowser" name="textBrowser"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8"?>
<PropertyList>
<generic>
<input>
<line_separator>\n</line_separator>
<var_separator>,</var_separator>
<chunk>
<name>aileron</name>
<node>/controls/flight/aileron</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>elevator</name>
<node>/controls/flight/elevator</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>rudder</name>
<node>/controls/flight/rudder</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>throttle</name>
<node>/controls/engines/engine/throttle</node>
<type>float</type>
<format>%f</format>
</chunk>
</input>
<output>
<line_separator>\n</line_separator>
<var_separator>,</var_separator>
<chunk>
<name>xRate</name>
<node>/fdm/jsbsim/velocities/p-rad_sec</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>yRate</name>
<node>/fdm/jsbsim/velocities/q-rad_sec</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>zRate</name>
<node>/fdm/jsbsim/velocities/r-rad_sec</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>xAccel</name>
<!-- /fdm/jsbsim/accelerations/a-pilot-x-ft_sec2 -->
<node>/accelerations/pilot/x-accel-fps_sec</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>yAccel</name>
<node>/accelerations/pilot/y-accel-fps_sec</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>zAccel</name>
<node>/accelerations/pilot/z-accel-fps_sec</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>Pitch</name>
<node>/orientation/pitch-deg</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>PitchRate</name>
<node>/orientation/pitch-rate-degps</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>Roll</name>
<node>/orientation/roll-deg</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>RollRate</name>
<node>/orientation/roll-rate-degps</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>Yaw</name>
<node>/orientation/heading-magnetic-deg</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>YawRate</name>
<node>/orientation/yaw-rate-degps</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>Latitude</name>
<node>/position/latitude-deg</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>Longitude</name>
<node>/position/longitude-deg</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>Heading</name>
<node>/orientation/heading-deg</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>Altitude</name>
<node>/position/altitude-ft</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>AltitudeAGL</name>
<node>/position/altitude-agl-ft</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>Groundspeed</name>
<node>/velocities/groundspeed-kt</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>Airspeed</name>
<node>/velocities/airspeed-kt</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>Temperature</name>
<node>/environment/temperature-degc</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>Temperature</name>
<node>/environment/temperature-degc</node>
<type>float</type>
<format>%f</format>
</chunk>
<chunk>
<name>Pressure</name>
<node>/environment/pressure-inhg</node>
<type>float</type>
<format>%f</format>
</chunk>
</output>
</generic>
</PropertyList>

View File

@ -47,6 +47,7 @@ SUBDIRS += plugin_emptygadget
# Map UAVGadget
plugin_map.subdir = map
plugin_map.depends = plugin_coreplugin
plugin_map.depends = plugin_uavobjects
SUBDIRS += plugin_map
# Scope UAVGadget
@ -54,17 +55,18 @@ plugin_scope.subdir = scope
plugin_scope.depends = plugin_coreplugin
SUBDIRS += plugin_scope
# ModelView UAVGadget
plugin_modelview.subdir = modelview
plugin_scope.depends = plugin_coreplugin
SUBDIRS += plugin_modelview
# UAVObject Browser Gadget
plugin_uavobjectbrowser.subdir = uavobjectbrowser
plugin_uavobjectbrowser.depends = plugin_coreplugin
plugin_uavobjectbrowser.depends = plugin_uavobjects
SUBDIRS += plugin_uavobjectbrowser
# ModelView UAVGadget
plugin_modelview.subdir = modelview
plugin_modelview.depends = plugin_coreplugin
plugin_modelview.depends = plugin_uavobjects
SUBDIRS += plugin_modelview
#Uploader Gadget
plugin_uploader.subdir = uploader
plugin_uploader.depends = plugin_coreplugin
@ -92,3 +94,10 @@ plugin_config.subdir = config
plugin_config.depends = plugin_coreplugin
SUBDIRS += plugin_config
#HITL simulation Gadget
plugin_hitl.subdir = hitl
plugin_hitl.depends = plugin_coreplugin
plugin_hitl.depends += plugin_uavobjects
plugin_hitl.depends += plugin_uavtalk
SUBDIRS += plugin_hitl