mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-29 07:24:13 +01:00
Merge remote-tracking branch 'origin/os/AeroSimRC' into next
This commit is contained in:
commit
ff0a3a156e
@ -234,17 +234,21 @@ static void AttitudeTask(void *parameters)
|
|||||||
|
|
||||||
AccelsData accels;
|
AccelsData accels;
|
||||||
GyrosData gyros;
|
GyrosData gyros;
|
||||||
int32_t retval;
|
int32_t retval = 0;
|
||||||
if(cc3d)
|
|
||||||
|
if (cc3d)
|
||||||
retval = updateSensorsCC3D(&accels, &gyros);
|
retval = updateSensorsCC3D(&accels, &gyros);
|
||||||
else
|
else
|
||||||
retval = updateSensors(&accels, &gyros);
|
retval = updateSensors(&accels, &gyros);
|
||||||
|
|
||||||
if(retval != 0)
|
// Only update attitude when sensor data is good
|
||||||
|
if (retval != 0)
|
||||||
AlarmsSet(SYSTEMALARMS_ALARM_ATTITUDE, SYSTEMALARMS_ALARM_ERROR);
|
AlarmsSet(SYSTEMALARMS_ALARM_ATTITUDE, SYSTEMALARMS_ALARM_ERROR);
|
||||||
else {
|
else {
|
||||||
// Only update attitude when sensor data is good
|
// Do not update attitude data in simulation mode
|
||||||
updateAttitude(&accels, &gyros);
|
if (!AttitudeActualReadOnly())
|
||||||
|
updateAttitude(&accels, &gyros);
|
||||||
|
|
||||||
AlarmsClear(SYSTEMALARMS_ALARM_ATTITUDE);
|
AlarmsClear(SYSTEMALARMS_ALARM_ATTITUDE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,6 +272,10 @@ static int32_t updateSensors(AccelsData * accels, GyrosData * gyros)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do not read raw sensor data in simulation mode
|
||||||
|
if (GyrosReadOnly() || AccelsReadOnly())
|
||||||
|
return 0;
|
||||||
|
|
||||||
// No accel data available
|
// No accel data available
|
||||||
if(PIOS_ADXL345_FifoElements() == 0)
|
if(PIOS_ADXL345_FifoElements() == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "ui_inputchannelform.h"
|
#include "ui_inputchannelform.h"
|
||||||
|
|
||||||
#include "manualcontrolsettings.h"
|
#include "manualcontrolsettings.h"
|
||||||
|
#include "gcsreceiver.h"
|
||||||
|
|
||||||
inputChannelForm::inputChannelForm(QWidget *parent,bool showlegend) :
|
inputChannelForm::inputChannelForm(QWidget *parent,bool showlegend) :
|
||||||
ConfigTaskWidget(parent),
|
ConfigTaskWidget(parent),
|
||||||
@ -115,7 +116,7 @@ void inputChannelForm::groupUpdated()
|
|||||||
count = 18;
|
count = 18;
|
||||||
break;
|
break;
|
||||||
case ManualControlSettings::CHANNELGROUPS_GCS:
|
case ManualControlSettings::CHANNELGROUPS_GCS:
|
||||||
count = 5;
|
count = GCSReceiver::CHANNEL_NUMELEM;
|
||||||
break;
|
break;
|
||||||
case ManualControlSettings::CHANNELGROUPS_NONE:
|
case ManualControlSettings::CHANNELGROUPS_NONE:
|
||||||
count = 0;
|
count = 0;
|
||||||
|
468
ground/openpilotgcs/src/plugins/hitlv2/aerosimrc.cpp
Normal file
468
ground/openpilotgcs/src/plugins/hitlv2/aerosimrc.cpp
Normal file
@ -0,0 +1,468 @@
|
|||||||
|
#include "aerosimrc.h"
|
||||||
|
#include <extensionsystem/pluginmanager.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
#include <coreplugin/threadmanager.h>
|
||||||
|
|
||||||
|
AeroSimRCSimulator::AeroSimRCSimulator(const SimulatorSettings ¶ms)
|
||||||
|
: Simulator(params)
|
||||||
|
{
|
||||||
|
udpCounterASrecv = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AeroSimRCSimulator::~AeroSimRCSimulator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AeroSimRCSimulator::setupProcess()
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AeroSimRCSimulator::setupUdpPorts(const QString &host, int inPort, int outPort)
|
||||||
|
{
|
||||||
|
Q_UNUSED(outPort)
|
||||||
|
if (inSocket->bind(QHostAddress(host), inPort))
|
||||||
|
emit processOutput("Successfully bound to address " + host + ", port " + QString::number(inPort) + "\n");
|
||||||
|
else
|
||||||
|
emit processOutput("Cannot bind to address " + host + ", port " + QString::number(inPort) + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AeroSimRCSimulator::transmitUpdate()
|
||||||
|
{
|
||||||
|
// read actuator output
|
||||||
|
ActuatorCommand::DataFields actCmdData;
|
||||||
|
actCmdData = actCommand->getData();
|
||||||
|
float channels[10];
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
qint16 ch = actCmdData.Channel[i];
|
||||||
|
float out = -1.0;
|
||||||
|
if (ch >= 1000 && ch <= 2000) {
|
||||||
|
ch -= 1000;
|
||||||
|
out = ((float)ch / 500.0) - 1.0;
|
||||||
|
}
|
||||||
|
channels[i] = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read flight status
|
||||||
|
FlightStatus::DataFields flightData;
|
||||||
|
flightData = flightStatus->getData();
|
||||||
|
quint8 armed;
|
||||||
|
quint8 mode;
|
||||||
|
armed = flightData.Armed;
|
||||||
|
mode = flightData.FlightMode;
|
||||||
|
|
||||||
|
QByteArray data;
|
||||||
|
// 50 - current size of values, 4(quint32) + 10*4(float) + 2(quint8) + 4(quint32)
|
||||||
|
data.resize(50);
|
||||||
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
|
||||||
|
stream << quint32(0x52434D44); // magic header, "RCMD"
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
stream << channels[i]; // channels
|
||||||
|
stream << armed << mode; // flight status
|
||||||
|
stream << udpCounterASrecv; // packet counter
|
||||||
|
|
||||||
|
if (outSocket->writeDatagram(data, QHostAddress(settings.remoteAddress), settings.outPort) == -1) {
|
||||||
|
qDebug() << "write failed: " << outSocket->errorString();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DBG_TIMERS
|
||||||
|
static int cntTX = 0;
|
||||||
|
if (cntTX >= 100) {
|
||||||
|
qDebug() << "TX=" << 1000.0 * 100 / timeTX.restart();
|
||||||
|
cntTX = 0;
|
||||||
|
} else {
|
||||||
|
++cntTX;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void AeroSimRCSimulator::processUpdate(const QByteArray &data)
|
||||||
|
{
|
||||||
|
// check size
|
||||||
|
if (data.size() > 188) {
|
||||||
|
qDebug() << "!!! big datagram: " << data.size();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray buf = data;
|
||||||
|
QDataStream stream(&buf, QIODevice::ReadOnly);
|
||||||
|
stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
|
||||||
|
|
||||||
|
// check magic header
|
||||||
|
quint32 magic;
|
||||||
|
stream >> magic;
|
||||||
|
if (magic != 0x4153494D) { // "AERO"
|
||||||
|
qDebug() << "wrong magic: " << magic << ", correct: " << quint32(0x4153494D);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float timeStep,
|
||||||
|
homeX, homeY, homeZ,
|
||||||
|
WpHX, WpHY, WpLat, WpLon,
|
||||||
|
posX, posY, posZ, // world
|
||||||
|
velX, velY, velZ, // world
|
||||||
|
angX, angY, angZ, // model
|
||||||
|
accX, accY, accZ, // model
|
||||||
|
lat, lon, agl, // world
|
||||||
|
yaw, pitch, roll, // model
|
||||||
|
volt, curr,
|
||||||
|
rx, ry, rz, fx, fy, fz, ux, uy, uz, // matrix
|
||||||
|
ch[8];
|
||||||
|
|
||||||
|
stream >> timeStep;
|
||||||
|
stream >> homeX >> homeY >> homeZ;
|
||||||
|
stream >> WpHX >> WpHY >> WpLat >> WpLon;
|
||||||
|
stream >> posX >> posY >> posZ;
|
||||||
|
stream >> velX >> velY >> velZ;
|
||||||
|
stream >> angX >> angY >> angZ;
|
||||||
|
stream >> accX >> accY >> accZ;
|
||||||
|
stream >> lat >> lon >> agl;
|
||||||
|
stream >> yaw >> pitch >> roll;
|
||||||
|
stream >> volt >> curr;
|
||||||
|
stream >> rx >> ry >> rz >> fx >> fy >> fz >> ux >> uy >> uz;
|
||||||
|
stream >> ch[0] >> ch[1] >> ch[2] >> ch[3] >> ch[4] >> ch[5] >> ch[6] >> ch[7];
|
||||||
|
stream >> udpCounterASrecv;
|
||||||
|
|
||||||
|
/**********************************************************************************************/
|
||||||
|
QTime currentTime = QTime::currentTime();
|
||||||
|
/**********************************************************************************************/
|
||||||
|
static bool firstRun = true;
|
||||||
|
if (settings.homeLocation) {
|
||||||
|
if (firstRun) {
|
||||||
|
HomeLocation::DataFields homeData;
|
||||||
|
homeData = posHome->getData();
|
||||||
|
|
||||||
|
homeData.Latitude = WpLat * 10e6;
|
||||||
|
homeData.Longitude = WpLon * 10e6;
|
||||||
|
homeData.Altitude = homeZ;
|
||||||
|
homeData.Set = HomeLocation::SET_TRUE;
|
||||||
|
|
||||||
|
posHome->setData(homeData);
|
||||||
|
|
||||||
|
firstRun = false;
|
||||||
|
}
|
||||||
|
if (settings.homeLocRate > 0) {
|
||||||
|
static QTime homeLocTime = currentTime;
|
||||||
|
if (homeLocTime.secsTo(currentTime) >= settings.homeLocRate) {
|
||||||
|
firstRun = true;
|
||||||
|
homeLocTime = currentTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**********************************************************************************************/
|
||||||
|
if (settings.attRaw || settings.attActual) {
|
||||||
|
QMatrix4x4 mat;
|
||||||
|
mat = QMatrix4x4( fy, fx, -fz, 0.0, // model matrix
|
||||||
|
ry, rx, -rz, 0.0, // (X,Y,Z) -> (+Y,+X,-Z)
|
||||||
|
-uy, -ux, uz, 0.0,
|
||||||
|
0.0, 0.0, 0.0, 1.0);
|
||||||
|
mat.optimize();
|
||||||
|
|
||||||
|
QQuaternion quat; // model quat
|
||||||
|
asMatrix2Quat(mat, quat);
|
||||||
|
|
||||||
|
// rotate gravity
|
||||||
|
QVector3D acc = QVector3D(accY, accX, -accZ); // accel (X,Y,Z) -> (+Y,+X,-Z)
|
||||||
|
QVector3D gee = QVector3D(0.0, 0.0, -GEE);
|
||||||
|
QQuaternion qWorld = quat.conjugate();
|
||||||
|
gee = qWorld.rotatedVector(gee);
|
||||||
|
acc += gee;
|
||||||
|
|
||||||
|
/*************************************************************************************/
|
||||||
|
if (settings.attRaw) {
|
||||||
|
Accels::DataFields accelsData;
|
||||||
|
accelsData = accels->getData();
|
||||||
|
Gyros::DataFields gyrosData;
|
||||||
|
gyrosData = gyros->getData();
|
||||||
|
|
||||||
|
gyrosData.x = angY * RAD2DEG; // gyros (X,Y,Z) -> (+Y,+X,-Z)
|
||||||
|
gyrosData.y = angX * RAD2DEG;
|
||||||
|
gyrosData.z = angZ * -RAD2DEG;
|
||||||
|
accelsData.x = acc.x();
|
||||||
|
accelsData.y = acc.y();
|
||||||
|
accelsData.z = acc.z();
|
||||||
|
|
||||||
|
accels->setData(accelsData);
|
||||||
|
gyros->setData(gyrosData);
|
||||||
|
}
|
||||||
|
/*************************************************************************************/
|
||||||
|
if (settings.attActHW) {
|
||||||
|
// do nothing
|
||||||
|
/*****************************************/
|
||||||
|
} else if (settings.attActSim) {
|
||||||
|
// take all data from simulator
|
||||||
|
AttitudeActual::DataFields attActData;
|
||||||
|
attActData = attActual->getData();
|
||||||
|
|
||||||
|
QVector3D rpy; // model roll, pitch, yaw
|
||||||
|
asMatrix2RPY(mat, rpy);
|
||||||
|
|
||||||
|
attActData.Roll = rpy.x();
|
||||||
|
attActData.Pitch = rpy.y();
|
||||||
|
attActData.Yaw = rpy.z();
|
||||||
|
attActData.q1 = quat.scalar();
|
||||||
|
attActData.q2 = quat.x();
|
||||||
|
attActData.q3 = quat.y();
|
||||||
|
attActData.q4 = quat.z();
|
||||||
|
|
||||||
|
attActual->setData(attActData);
|
||||||
|
/*****************************************/
|
||||||
|
} else if (settings.attActCalc) {
|
||||||
|
// calculate RPY with code from Attitude module
|
||||||
|
AttitudeActual::DataFields attActData;
|
||||||
|
attActData = attActual->getData();
|
||||||
|
|
||||||
|
static float q[4] = {1, 0, 0, 0};
|
||||||
|
static float gyro_correct_int2 = 0;
|
||||||
|
|
||||||
|
float dT = timeStep;
|
||||||
|
|
||||||
|
AttitudeSettings::DataFields attSettData = attSettings->getData();
|
||||||
|
float accelKp = attSettData.AccelKp * 0.1666666666666667;
|
||||||
|
float accelKi = attSettData.AccelKp * 0.1666666666666667;
|
||||||
|
float yawBiasRate = attSettData.YawBiasRate;
|
||||||
|
|
||||||
|
// calibrate sensors on arming
|
||||||
|
if (flightStatus->getData().Armed == FlightStatus::ARMED_ARMING) {
|
||||||
|
accelKp = 2.0;
|
||||||
|
accelKi = 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
float gyro[3] = {angY * RAD2DEG, angX * RAD2DEG, angZ * -RAD2DEG};
|
||||||
|
float attRawAcc[3] = {acc.x(), acc.y(), acc.z()};
|
||||||
|
|
||||||
|
// code from Attitude module begin ///////////////////////////////
|
||||||
|
float *accels = attRawAcc;
|
||||||
|
float grot[3];
|
||||||
|
float accel_err[3];
|
||||||
|
|
||||||
|
// Rotate gravity to body frame and cross with accels
|
||||||
|
grot[0] = -(2 * (q[1] * q[3] - q[0] * q[2]));
|
||||||
|
grot[1] = -(2 * (q[2] * q[3] + q[0] * q[1]));
|
||||||
|
grot[2] = -(q[0] * q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3]);
|
||||||
|
|
||||||
|
// CrossProduct
|
||||||
|
{
|
||||||
|
accel_err[0] = accels[1]*grot[2] - grot[1]*accels[2];
|
||||||
|
accel_err[1] = grot[0]*accels[2] - accels[0]*grot[2];
|
||||||
|
accel_err[2] = accels[0]*grot[1] - grot[0]*accels[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Account for accel magnitude
|
||||||
|
float accel_mag = sqrt(accels[0] * accels[0] + accels[1] * accels[1] + accels[2] * accels[2]);
|
||||||
|
accel_err[0] /= accel_mag;
|
||||||
|
accel_err[1] /= accel_mag;
|
||||||
|
accel_err[2] /= accel_mag;
|
||||||
|
|
||||||
|
// Accumulate integral of error. Scale here so that units are (deg/s) but Ki has units of s
|
||||||
|
gyro_correct_int2 += -gyro[2] * yawBiasRate;
|
||||||
|
|
||||||
|
// Correct rates based on error, integral component dealt with in updateSensors
|
||||||
|
gyro[0] += accel_err[0] * accelKp / dT;
|
||||||
|
gyro[1] += accel_err[1] * accelKp / dT;
|
||||||
|
gyro[2] += accel_err[2] * accelKp / dT + gyro_correct_int2;
|
||||||
|
|
||||||
|
// Work out time derivative from INSAlgo writeup
|
||||||
|
// Also accounts for the fact that gyros are in deg/s
|
||||||
|
float qdot[4];
|
||||||
|
qdot[0] = (-q[1] * gyro[0] - q[2] * gyro[1] - q[3] * gyro[2]) * dT * M_PI / 180 / 2;
|
||||||
|
qdot[1] = (+q[0] * gyro[0] - q[3] * gyro[1] + q[2] * gyro[2]) * dT * M_PI / 180 / 2;
|
||||||
|
qdot[2] = (+q[3] * gyro[0] + q[0] * gyro[1] - q[1] * gyro[2]) * dT * M_PI / 180 / 2;
|
||||||
|
qdot[3] = (-q[2] * gyro[0] + q[1] * gyro[1] + q[0] * gyro[2]) * dT * M_PI / 180 / 2;
|
||||||
|
|
||||||
|
// Take a time step
|
||||||
|
q[0] += qdot[0];
|
||||||
|
q[1] += qdot[1];
|
||||||
|
q[2] += qdot[2];
|
||||||
|
q[3] += qdot[3];
|
||||||
|
|
||||||
|
if(q[0] < 0) {
|
||||||
|
q[0] = -q[0];
|
||||||
|
q[1] = -q[1];
|
||||||
|
q[2] = -q[2];
|
||||||
|
q[3] = -q[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renomalize
|
||||||
|
float qmag = sqrt((q[0] * q[0]) + (q[1] * q[1]) + (q[2] * q[2]) + (q[3] * q[3]));
|
||||||
|
q[0] /= qmag;
|
||||||
|
q[1] /= qmag;
|
||||||
|
q[2] /= qmag;
|
||||||
|
q[3] /= qmag;
|
||||||
|
|
||||||
|
// If quaternion has become inappropriately short or is nan reinit.
|
||||||
|
// THIS SHOULD NEVER ACTUALLY HAPPEN
|
||||||
|
if((fabs(qmag) < 1e-3) || (qmag != qmag)) {
|
||||||
|
q[0] = 1;
|
||||||
|
q[1] = 0;
|
||||||
|
q[2] = 0;
|
||||||
|
q[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rpy2[3];
|
||||||
|
// Quaternion2RPY
|
||||||
|
{
|
||||||
|
float q0s, q1s, q2s, q3s;
|
||||||
|
q0s = q[0] * q[0];
|
||||||
|
q1s = q[1] * q[1];
|
||||||
|
q2s = q[2] * q[2];
|
||||||
|
q3s = q[3] * q[3];
|
||||||
|
|
||||||
|
float R13, R11, R12, R23, R33;
|
||||||
|
R13 = 2 * (q[1] * q[3] - q[0] * q[2]);
|
||||||
|
R11 = q0s + q1s - q2s - q3s;
|
||||||
|
R12 = 2 * (q[1] * q[2] + q[0] * q[3]);
|
||||||
|
R23 = 2 * (q[2] * q[3] + q[0] * q[1]);
|
||||||
|
R33 = q0s - q1s - q2s + q3s;
|
||||||
|
|
||||||
|
rpy2[1] = RAD2DEG * asinf(-R13); // pitch always between -pi/2 to pi/2
|
||||||
|
rpy2[2] = RAD2DEG * atan2f(R12, R11);
|
||||||
|
rpy2[0] = RAD2DEG * atan2f(R23, R33);
|
||||||
|
}
|
||||||
|
|
||||||
|
attActData.Roll = rpy2[0];
|
||||||
|
attActData.Pitch = rpy2[1];
|
||||||
|
attActData.Yaw = rpy2[2];
|
||||||
|
attActData.q1 = q[0];
|
||||||
|
attActData.q2 = q[1];
|
||||||
|
attActData.q3 = q[2];
|
||||||
|
attActData.q4 = q[3];
|
||||||
|
attActual->setData(attActData);
|
||||||
|
/*****************************************/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**********************************************************************************************/
|
||||||
|
if (settings.gcsReciever) {
|
||||||
|
static QTime gcsRcvrTime = currentTime;
|
||||||
|
if (!settings.manualOutput || gcsRcvrTime.msecsTo(currentTime) >= settings.outputRate) {
|
||||||
|
GCSReceiver::DataFields gcsRcvrData;
|
||||||
|
gcsRcvrData = gcsReceiver->getData();
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; ++i)
|
||||||
|
gcsRcvrData.Channel[i] = 1500 + (ch[i] * 500);
|
||||||
|
|
||||||
|
gcsReceiver->setData(gcsRcvrData);
|
||||||
|
if (settings.manualOutput)
|
||||||
|
gcsRcvrTime = currentTime;
|
||||||
|
}
|
||||||
|
} else if (settings.manualControl) {
|
||||||
|
// not implemented yet
|
||||||
|
}
|
||||||
|
/**********************************************************************************************/
|
||||||
|
if (settings.gpsPosition) {
|
||||||
|
static QTime gpsPosTime = currentTime;
|
||||||
|
if (gpsPosTime.msecsTo(currentTime) >= settings.gpsPosRate) {
|
||||||
|
GPSPosition::DataFields gpsPosData;
|
||||||
|
gpsPosData = gpsPosition->getData();
|
||||||
|
|
||||||
|
gpsPosData.Altitude = posZ;
|
||||||
|
gpsPosData.Heading = yaw * RAD2DEG;
|
||||||
|
gpsPosData.Latitude = lat * 10e6;
|
||||||
|
gpsPosData.Longitude = lon * 10e6;
|
||||||
|
gpsPosData.Groundspeed = qSqrt(velX * velX + velY * velY);
|
||||||
|
gpsPosData.GeoidSeparation = 0.0;
|
||||||
|
gpsPosData.Satellites = 8;
|
||||||
|
gpsPosData.PDOP = 3.0;
|
||||||
|
gpsPosData.Status = GPSPosition::STATUS_FIX3D;
|
||||||
|
|
||||||
|
gpsPosition->setData(gpsPosData);
|
||||||
|
gpsPosTime = currentTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**********************************************************************************************/
|
||||||
|
if (settings.sonarAltitude) {
|
||||||
|
static QTime sonarAltTime = currentTime;
|
||||||
|
if (sonarAltTime.msecsTo(currentTime) >= settings.sonarAltRate) {
|
||||||
|
SonarAltitude::DataFields sonarAltData;
|
||||||
|
sonarAltData = sonarAlt->getData();
|
||||||
|
|
||||||
|
float sAlt = settings.sonarMaxAlt;
|
||||||
|
// 0.35 rad ~= 20 degree
|
||||||
|
if ((agl < (sAlt * 2.0)) && (roll < 0.35) && (pitch < 0.35)) {
|
||||||
|
float x = agl * qTan(roll);
|
||||||
|
float y = agl * qTan(pitch);
|
||||||
|
float h = qSqrt(x*x + y*y + agl*agl);
|
||||||
|
sAlt = qMin(h, sAlt);
|
||||||
|
}
|
||||||
|
|
||||||
|
sonarAltData.Altitude = sAlt;
|
||||||
|
sonarAlt->setData(sonarAltData);
|
||||||
|
sonarAltTime = currentTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**********************************************************************************************/
|
||||||
|
/*
|
||||||
|
BaroAltitude::DataFields altActData;
|
||||||
|
altActData = altActual->getData();
|
||||||
|
altActData.Altitude = posZ;
|
||||||
|
altActual->setData(altActData);
|
||||||
|
|
||||||
|
PositionActual::DataFields posActData;
|
||||||
|
posActData = posActual->getData();
|
||||||
|
posActData.North = posY * 100;
|
||||||
|
posActData.East = posX * 100;
|
||||||
|
posActData.Down = posZ * -100;
|
||||||
|
posActual->setData(posActData);
|
||||||
|
|
||||||
|
VelocityActual::DataFields velActData;
|
||||||
|
velActData = velActual->getData();
|
||||||
|
velActData.North = velY * 100;
|
||||||
|
velActData.East = velX * 100;
|
||||||
|
velActData.Down = velZ * 100;
|
||||||
|
velActual->setData(velActData);
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DBG_TIMERS
|
||||||
|
static int cntRX = 0;
|
||||||
|
if (cntRX >= 100) {
|
||||||
|
qDebug() << "RX=" << 1000.0 * 100 / timeRX.restart();
|
||||||
|
cntRX = 0;
|
||||||
|
} else {
|
||||||
|
++cntRX;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// transfomations
|
||||||
|
|
||||||
|
void AeroSimRCSimulator::asMatrix2Quat(const QMatrix4x4 &m, QQuaternion &q)
|
||||||
|
{
|
||||||
|
qreal w, x, y, z;
|
||||||
|
|
||||||
|
// w always >= 0
|
||||||
|
w = qSqrt(qMax(0.0, 1.0 + m(0, 0) + m(1, 1) + m(2, 2))) / 2.0;
|
||||||
|
x = qSqrt(qMax(0.0, 1.0 + m(0, 0) - m(1, 1) - m(2, 2))) / 2.0;
|
||||||
|
y = qSqrt(qMax(0.0, 1.0 - m(0, 0) + m(1, 1) - m(2, 2))) / 2.0;
|
||||||
|
z = qSqrt(qMax(0.0, 1.0 - m(0, 0) - m(1, 1) + m(2, 2))) / 2.0;
|
||||||
|
|
||||||
|
x = copysign(x, (m(1, 2) - m(2, 1)));
|
||||||
|
y = copysign(y, (m(2, 0) - m(0, 2)));
|
||||||
|
z = copysign(z, (m(0, 1) - m(1, 0)));
|
||||||
|
|
||||||
|
q.setScalar(w);
|
||||||
|
q.setX(x);
|
||||||
|
q.setY(y);
|
||||||
|
q.setZ(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AeroSimRCSimulator::asMatrix2RPY(const QMatrix4x4 &m, QVector3D &rpy)
|
||||||
|
{
|
||||||
|
qreal roll, pitch, yaw;
|
||||||
|
|
||||||
|
if (qFabs(m(0, 2)) > 0.998) {
|
||||||
|
// ~86.3°, gimbal lock
|
||||||
|
roll = 0.0;
|
||||||
|
pitch = copysign(M_PI_2, -m(0, 2));
|
||||||
|
yaw = qAtan2(-m(1, 0), m(1, 1));
|
||||||
|
} else {
|
||||||
|
roll = qAtan2(m(1, 2), m(2, 2));
|
||||||
|
pitch = qAsin(-m(0, 2));
|
||||||
|
yaw = qAtan2(m(0, 1), m(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
rpy.setX(roll * RAD2DEG);
|
||||||
|
rpy.setY(pitch * RAD2DEG);
|
||||||
|
rpy.setZ(yaw * RAD2DEG);
|
||||||
|
}
|
46
ground/openpilotgcs/src/plugins/hitlv2/aerosimrc.h
Normal file
46
ground/openpilotgcs/src/plugins/hitlv2/aerosimrc.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef AEROSIMRC_H
|
||||||
|
#define AEROSIMRC_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QVector3D>
|
||||||
|
#include <QQuaternion>
|
||||||
|
#include <QMatrix4x4>
|
||||||
|
#include "simulatorv2.h"
|
||||||
|
|
||||||
|
class AeroSimRCSimulator: public Simulator
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
AeroSimRCSimulator(const SimulatorSettings ¶ms);
|
||||||
|
~AeroSimRCSimulator();
|
||||||
|
|
||||||
|
bool setupProcess();
|
||||||
|
void setupUdpPorts(const QString& host, int inPort, int outPort);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void transmitUpdate();
|
||||||
|
|
||||||
|
private:
|
||||||
|
quint32 udpCounterASrecv; //keeps track of udp packets received by ASim
|
||||||
|
|
||||||
|
void processUpdate(const QByteArray &data);
|
||||||
|
|
||||||
|
void asMatrix2Quat(const QMatrix4x4 &m, QQuaternion &q);
|
||||||
|
void asMatrix2RPY(const QMatrix4x4 &m, QVector3D &rpy);
|
||||||
|
};
|
||||||
|
|
||||||
|
class AeroSimRCSimulatorCreator : public SimulatorCreator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AeroSimRCSimulatorCreator(const QString &classId, const QString &description)
|
||||||
|
: SimulatorCreator (classId, description)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Simulator* createSimulator(const SimulatorSettings ¶ms)
|
||||||
|
{
|
||||||
|
return new AeroSimRCSimulator(params);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // AEROSIMRC_H
|
12
ground/openpilotgcs/src/plugins/hitlv2/hitlv2.pluginspec
Normal file
12
ground/openpilotgcs/src/plugins/hitlv2/hitlv2.pluginspec
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<plugin name="HITLv2" version="1.0.0" compatVersion="1.0.0">
|
||||||
|
<vendor>The OpenPilot Project</vendor>
|
||||||
|
<copyright>(C) 2011 OpenPilot Project</copyright>
|
||||||
|
<license>The GNU Public License (GPL) Version 3</license>
|
||||||
|
<description>Hardware In The Loop Simulation (v2)</description>
|
||||||
|
<url>http://www.openpilot.org</url>
|
||||||
|
<dependencyList>
|
||||||
|
<dependency name="Core" version="1.0.0"/>
|
||||||
|
<dependency name="UAVObjects" version="1.0.0"/>
|
||||||
|
<dependency name="UAVTalk" version="1.0.0"/>
|
||||||
|
</dependencyList>
|
||||||
|
</plugin>
|
27
ground/openpilotgcs/src/plugins/hitlv2/hitlv2.pro
Normal file
27
ground/openpilotgcs/src/plugins/hitlv2/hitlv2.pro
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
TEMPLATE = lib
|
||||||
|
TARGET = HITLV2
|
||||||
|
QT += network
|
||||||
|
include(../../openpilotgcsplugin.pri)
|
||||||
|
include(hitlv2_dependencies.pri)
|
||||||
|
HEADERS += \
|
||||||
|
aerosimrc.h \
|
||||||
|
hitlv2configuration.h \
|
||||||
|
hitlv2factory.h \
|
||||||
|
hitlv2gadget.h \
|
||||||
|
hitlv2optionspage.h \
|
||||||
|
hitlv2plugin.h \
|
||||||
|
hitlv2widget.h \
|
||||||
|
simulatorv2.h
|
||||||
|
SOURCES += \
|
||||||
|
aerosimrc.cpp \
|
||||||
|
hitlv2configuration.cpp \
|
||||||
|
hitlv2factory.cpp \
|
||||||
|
hitlv2gadget.cpp \
|
||||||
|
hitlv2optionspage.cpp \
|
||||||
|
hitlv2plugin.cpp \
|
||||||
|
hitlv2widget.cpp \
|
||||||
|
simulatorv2.cpp
|
||||||
|
OTHER_FILES += hitlv2.pluginspec
|
||||||
|
FORMS += \
|
||||||
|
hitlv2optionspage.ui \
|
||||||
|
hitlv2widget.ui
|
@ -0,0 +1,4 @@
|
|||||||
|
include(../../plugins/uavobjects/uavobjects.pri)
|
||||||
|
include(../../plugins/uavtalk/uavtalk.pri)
|
||||||
|
#include(../../plugins/coreplugin/coreplugin.pri)
|
||||||
|
#include(../../libs/utils/utils.pri)
|
178
ground/openpilotgcs/src/plugins/hitlv2/hitlv2configuration.cpp
Normal file
178
ground/openpilotgcs/src/plugins/hitlv2/hitlv2configuration.cpp
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file hitlconfiguration.cpp
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 "hitlv2configuration.h"
|
||||||
|
|
||||||
|
HITLConfiguration::HITLConfiguration(QString classId,
|
||||||
|
QSettings* qSettings,
|
||||||
|
QObject *parent)
|
||||||
|
: IUAVGadgetConfiguration(classId, parent)
|
||||||
|
{
|
||||||
|
// qDebug() << "HITLV2Configuration";
|
||||||
|
// default values
|
||||||
|
QString simulatorId = "";
|
||||||
|
QString hostAddress = "127.0.0.1";
|
||||||
|
int inPort = 40100;
|
||||||
|
QString remoteAddress = "127.0.0.1";
|
||||||
|
int outPort = 40200;
|
||||||
|
QString binPath = "";
|
||||||
|
QString dataPath = "";
|
||||||
|
|
||||||
|
bool homeLocation = true;
|
||||||
|
quint16 homeLocRate = 0;
|
||||||
|
|
||||||
|
bool attRaw = true;
|
||||||
|
quint8 attRawRate = 20;
|
||||||
|
|
||||||
|
bool attActual = true;
|
||||||
|
bool attActHW = false;
|
||||||
|
bool attActSim = true;
|
||||||
|
bool attActCalc = false;
|
||||||
|
|
||||||
|
bool sonarAltitude = false;
|
||||||
|
float sonarMaxAlt = 5.0;
|
||||||
|
quint16 sonarAltRate = 50;
|
||||||
|
|
||||||
|
bool gpsPosition = true;
|
||||||
|
quint16 gpsPosRate = 200;
|
||||||
|
|
||||||
|
bool inputCommand = true;
|
||||||
|
bool gcsReciever = true;
|
||||||
|
bool manualControl = false;
|
||||||
|
|
||||||
|
bool manualOutput = false;
|
||||||
|
quint8 outputRate = 20;
|
||||||
|
|
||||||
|
// if a saved configuration exists load it
|
||||||
|
if (qSettings != 0) {
|
||||||
|
settings.simulatorId = qSettings->value("simulatorId", simulatorId).toString();
|
||||||
|
settings.hostAddress = qSettings->value("hostAddress", hostAddress).toString();
|
||||||
|
settings.inPort = qSettings->value("inPort", inPort).toInt();
|
||||||
|
settings.remoteAddress = qSettings->value("remoteAddress", remoteAddress).toString();
|
||||||
|
settings.outPort = qSettings->value("outPort", outPort).toInt();
|
||||||
|
settings.binPath = qSettings->value("binPath", binPath).toString();
|
||||||
|
settings.dataPath = qSettings->value("dataPath", dataPath).toString();
|
||||||
|
|
||||||
|
settings.homeLocation = qSettings->value("homeLocation", homeLocation).toBool();
|
||||||
|
settings.homeLocRate = qSettings->value("homeLocRate", homeLocRate).toInt();
|
||||||
|
|
||||||
|
settings.attRaw = qSettings->value("attRaw", attRaw).toBool();
|
||||||
|
settings.attRawRate = qSettings->value("attRawRate", attRawRate).toInt();
|
||||||
|
|
||||||
|
settings.attActual = qSettings->value("attActual", attActual).toBool();
|
||||||
|
settings.attActHW = qSettings->value("attActHW", attActHW).toBool();
|
||||||
|
settings.attActSim = qSettings->value("attActSim", attActSim).toBool();
|
||||||
|
settings.attActCalc = qSettings->value("attActCalc", attActCalc).toBool();
|
||||||
|
|
||||||
|
settings.sonarAltitude = qSettings->value("sonarAltitude", sonarAltitude).toBool();
|
||||||
|
settings.sonarMaxAlt = qSettings->value("sonarMaxAlt", sonarMaxAlt).toFloat();
|
||||||
|
settings.sonarAltRate = qSettings->value("sonarAltRate", sonarAltRate).toInt();
|
||||||
|
|
||||||
|
settings.gpsPosition = qSettings->value("gpsPosition", gpsPosition).toBool();
|
||||||
|
settings.gpsPosRate = qSettings->value("gpsPosRate", gpsPosRate).toInt();
|
||||||
|
|
||||||
|
settings.inputCommand = qSettings->value("inputCommand", inputCommand).toBool();
|
||||||
|
settings.gcsReciever = qSettings->value("gcsReciever", gcsReciever).toBool();
|
||||||
|
settings.manualControl = qSettings->value("manualControl", manualControl).toBool();
|
||||||
|
settings.manualOutput = qSettings->value("manualOutput", manualOutput).toBool();
|
||||||
|
settings.outputRate = qSettings->value("outputRate", outputRate).toInt();
|
||||||
|
} else {
|
||||||
|
settings.simulatorId = simulatorId;
|
||||||
|
settings.hostAddress = hostAddress;
|
||||||
|
settings.inPort = inPort;
|
||||||
|
settings.remoteAddress = remoteAddress;
|
||||||
|
settings.outPort = outPort;
|
||||||
|
settings.binPath = binPath;
|
||||||
|
settings.dataPath = dataPath;
|
||||||
|
|
||||||
|
settings.homeLocation = homeLocation;
|
||||||
|
settings.homeLocRate = homeLocRate;
|
||||||
|
|
||||||
|
settings.attRaw = attRaw;
|
||||||
|
settings.attRawRate = attRawRate;
|
||||||
|
|
||||||
|
settings.attActual = attActual;
|
||||||
|
settings.attActHW = attActHW;
|
||||||
|
settings.attActSim = attActSim;
|
||||||
|
settings.attActCalc = attActCalc;
|
||||||
|
|
||||||
|
settings.sonarAltitude = sonarAltitude;
|
||||||
|
settings.sonarMaxAlt = sonarMaxAlt;
|
||||||
|
settings.sonarAltRate = sonarAltRate;
|
||||||
|
|
||||||
|
settings.gpsPosition = gpsPosition;
|
||||||
|
settings.gpsPosRate = gpsPosRate;
|
||||||
|
|
||||||
|
settings.inputCommand = inputCommand;
|
||||||
|
settings.gcsReciever = gcsReciever;
|
||||||
|
settings.manualControl = manualControl;
|
||||||
|
settings.manualOutput = manualOutput;
|
||||||
|
settings.outputRate = outputRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IUAVGadgetConfiguration *HITLConfiguration::clone()
|
||||||
|
{
|
||||||
|
HITLConfiguration *m = new HITLConfiguration(this->classId());
|
||||||
|
m->settings = settings;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLConfiguration::saveConfig(QSettings* qSettings) const
|
||||||
|
{
|
||||||
|
qSettings->setValue("simulatorId", settings.simulatorId);
|
||||||
|
qSettings->setValue("hostAddress", settings.hostAddress);
|
||||||
|
qSettings->setValue("inPort", settings.inPort);
|
||||||
|
qSettings->setValue("remoteAddress", settings.remoteAddress);
|
||||||
|
qSettings->setValue("outPort", settings.outPort);
|
||||||
|
qSettings->setValue("binPath", settings.binPath);
|
||||||
|
qSettings->setValue("dataPath", settings.dataPath);
|
||||||
|
|
||||||
|
qSettings->setValue("homeLocation", settings.homeLocation);
|
||||||
|
qSettings->setValue("homeLocRate", settings.homeLocRate);
|
||||||
|
|
||||||
|
qSettings->setValue("attRaw", settings.attRaw);
|
||||||
|
qSettings->setValue("attRawRate", settings.attRawRate);
|
||||||
|
|
||||||
|
qSettings->setValue("attActual", settings.attActual);
|
||||||
|
qSettings->setValue("attActHW", settings.attActHW);
|
||||||
|
qSettings->setValue("attActSim", settings.attActSim);
|
||||||
|
qSettings->setValue("attActCalc", settings.attActCalc);
|
||||||
|
|
||||||
|
qSettings->setValue("sonarAltitude", settings.sonarAltitude);
|
||||||
|
qSettings->setValue("sonarMaxAlt", settings.sonarMaxAlt);
|
||||||
|
qSettings->setValue("sonarAltRate", settings.sonarAltRate);
|
||||||
|
|
||||||
|
qSettings->setValue("gpsPosition", settings.gpsPosition);
|
||||||
|
qSettings->setValue("gpsPosRate", settings.gpsPosRate);
|
||||||
|
|
||||||
|
qSettings->setValue("inputCommand", settings.inputCommand);
|
||||||
|
qSettings->setValue("gcsReciever", settings.gcsReciever);
|
||||||
|
qSettings->setValue("manualControl", settings.manualControl);
|
||||||
|
qSettings->setValue("manualOutput", settings.manualOutput);
|
||||||
|
qSettings->setValue("outputRate", settings.outputRate);
|
||||||
|
}
|
61
ground/openpilotgcs/src/plugins/hitlv2/hitlv2configuration.h
Normal file
61
ground/openpilotgcs/src/plugins/hitlv2/hitlv2configuration.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file hitlconfiguration.h
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 HITLV2CONFIGURATION_H
|
||||||
|
#define HITLV2CONFIGURATION_H
|
||||||
|
|
||||||
|
#include <coreplugin/iuavgadgetconfiguration.h>
|
||||||
|
#include <QtGui/QColor>
|
||||||
|
#include <QString>
|
||||||
|
#include <simulatorv2.h>
|
||||||
|
|
||||||
|
using namespace Core;
|
||||||
|
|
||||||
|
class HITLConfiguration : public IUAVGadgetConfiguration
|
||||||
|
{
|
||||||
|
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(SimulatorSettings settings READ Settings WRITE setSimulatorSettings)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit HITLConfiguration(QString classId, QSettings* qSettings = 0, QObject *parent = 0);
|
||||||
|
|
||||||
|
void saveConfig(QSettings* settings) const;
|
||||||
|
IUAVGadgetConfiguration *clone();
|
||||||
|
|
||||||
|
SimulatorSettings Settings() const { return settings; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setSimulatorSettings (const SimulatorSettings& params ) { settings = params; }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
SimulatorSettings settings;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HITLV2CONFIGURATION_H
|
58
ground/openpilotgcs/src/plugins/hitlv2/hitlv2factory.cpp
Normal file
58
ground/openpilotgcs/src/plugins/hitlv2/hitlv2factory.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file hitlfactory.cpp
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 "hitlv2factory.h"
|
||||||
|
#include "hitlv2widget.h"
|
||||||
|
#include "hitlv2gadget.h"
|
||||||
|
#include "hitlv2configuration.h"
|
||||||
|
#include "hitlv2optionspage.h"
|
||||||
|
#include <coreplugin/iuavgadget.h>
|
||||||
|
|
||||||
|
HITLFactory::HITLFactory(QObject *parent)
|
||||||
|
: IUAVGadgetFactory(QString("HITLv2"), tr("HITL Simulation (v2)"), parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HITLFactory::~HITLFactory()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Core::IUAVGadget* HITLFactory::createGadget(QWidget *parent)
|
||||||
|
{
|
||||||
|
HITLWidget* gadgetWidget = new HITLWidget(parent);
|
||||||
|
return new HITLGadget(QString("HITLv2"), gadgetWidget, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
IUAVGadgetConfiguration *HITLFactory::createConfiguration(QSettings* qSettings)
|
||||||
|
{
|
||||||
|
return new HITLConfiguration(QString("HITLv2"), qSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOptionsPage *HITLFactory::createOptionsPage(IUAVGadgetConfiguration *config)
|
||||||
|
{
|
||||||
|
return new HITLOptionsPage(qobject_cast<HITLConfiguration*>(config));
|
||||||
|
}
|
||||||
|
|
52
ground/openpilotgcs/src/plugins/hitlv2/hitlv2factory.h
Normal file
52
ground/openpilotgcs/src/plugins/hitlv2/hitlv2factory.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file hitlfactory.h
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 HITLV2FACTORY_H
|
||||||
|
#define HITLV2FACTORY_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();
|
||||||
|
|
||||||
|
IUAVGadget *createGadget(QWidget *parent);
|
||||||
|
IUAVGadgetConfiguration *createConfiguration(QSettings* qSettings);
|
||||||
|
IOptionsPage *createOptionsPage(IUAVGadgetConfiguration *config);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HITLV2FACTORY_H
|
49
ground/openpilotgcs/src/plugins/hitlv2/hitlv2gadget.cpp
Normal file
49
ground/openpilotgcs/src/plugins/hitlv2/hitlv2gadget.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file hitl.cpp
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 "hitlv2gadget.h"
|
||||||
|
#include "hitlv2widget.h"
|
||||||
|
#include "hitlv2configuration.h"
|
||||||
|
#include "simulatorv2.h"
|
||||||
|
|
||||||
|
HITLGadget::HITLGadget(QString classId, HITLWidget *widget, QWidget *parent) :
|
||||||
|
IUAVGadget(classId, parent),
|
||||||
|
m_widget(widget)
|
||||||
|
{
|
||||||
|
connect(this, SIGNAL(changeConfiguration(void)), m_widget, SLOT(stopButtonClicked(void)));
|
||||||
|
}
|
||||||
|
|
||||||
|
HITLGadget::~HITLGadget()
|
||||||
|
{
|
||||||
|
delete m_widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLGadget::loadConfiguration(IUAVGadgetConfiguration* config)
|
||||||
|
{
|
||||||
|
HITLConfiguration *m = qobject_cast<HITLConfiguration*>(config);
|
||||||
|
emit changeConfiguration();
|
||||||
|
m_widget->setSettingParameters(m->Settings());
|
||||||
|
}
|
60
ground/openpilotgcs/src/plugins/hitlv2/hitlv2gadget.h
Normal file
60
ground/openpilotgcs/src/plugins/hitlv2/hitlv2gadget.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file hitl.h
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 HITLV2_H
|
||||||
|
#define HITLV2_H
|
||||||
|
|
||||||
|
#include <coreplugin/iuavgadget.h>
|
||||||
|
#include "hitlv2widget.h"
|
||||||
|
|
||||||
|
class IUAVGadget;
|
||||||
|
class QWidget;
|
||||||
|
class QString;
|
||||||
|
class Simulator;
|
||||||
|
|
||||||
|
using namespace Core;
|
||||||
|
|
||||||
|
class HITLGadget : public Core::IUAVGadget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
HITLGadget(QString classId, HITLWidget *widget, QWidget *parent = 0);
|
||||||
|
~HITLGadget();
|
||||||
|
|
||||||
|
QWidget *widget() { return m_widget; }
|
||||||
|
void loadConfiguration(IUAVGadgetConfiguration* config);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void changeConfiguration();
|
||||||
|
|
||||||
|
private:
|
||||||
|
HITLWidget* m_widget;
|
||||||
|
Simulator* simulator;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HITLV2_H
|
146
ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.cpp
Normal file
146
ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.cpp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file hitloptionspage.cpp
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 "hitlv2optionspage.h"
|
||||||
|
#include "hitlv2configuration.h"
|
||||||
|
#include "ui_hitlv2optionspage.h"
|
||||||
|
#include "hitlv2plugin.h"
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QtAlgorithms>
|
||||||
|
#include <QStringList>
|
||||||
|
#include "simulatorv2.h"
|
||||||
|
|
||||||
|
HITLOptionsPage::HITLOptionsPage(HITLConfiguration *conf, QObject *parent) :
|
||||||
|
IOptionsPage(parent),
|
||||||
|
config(conf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *HITLOptionsPage::createPage(QWidget *parent)
|
||||||
|
{
|
||||||
|
// qDebug() << "HITLOptionsPage::createPage";
|
||||||
|
// Create page
|
||||||
|
m_optionsPage = new Ui::HITLOptionsPage();
|
||||||
|
QWidget* optionsPageWidget = new QWidget;
|
||||||
|
m_optionsPage->setupUi(optionsPageWidget);
|
||||||
|
int index = 0;
|
||||||
|
foreach (SimulatorCreator* creator, HITLPlugin::typeSimulators)
|
||||||
|
m_optionsPage->chooseFlightSimulator->insertItem(index++, creator->Description(), creator->ClassId());
|
||||||
|
|
||||||
|
m_optionsPage->executablePath->setExpectedKind(Utils::PathChooser::File);
|
||||||
|
m_optionsPage->executablePath->setPromptDialogTitle(tr("Choose flight simulator executable"));
|
||||||
|
m_optionsPage->dataPath->setExpectedKind(Utils::PathChooser::Directory);
|
||||||
|
m_optionsPage->dataPath->setPromptDialogTitle(tr("Choose flight simulator data directory"));
|
||||||
|
|
||||||
|
// Restore the contents from the settings:
|
||||||
|
foreach (SimulatorCreator* creator, HITLPlugin::typeSimulators) {
|
||||||
|
QString id = config->Settings().simulatorId;
|
||||||
|
if (creator->ClassId() == id)
|
||||||
|
m_optionsPage->chooseFlightSimulator->setCurrentIndex(HITLPlugin::typeSimulators.indexOf(creator));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_optionsPage->hostAddress->setText(config->Settings().hostAddress);
|
||||||
|
m_optionsPage->inputPort->setText(QString::number(config->Settings().inPort));
|
||||||
|
m_optionsPage->remoteAddress->setText(config->Settings().remoteAddress);
|
||||||
|
m_optionsPage->outputPort->setText(QString::number(config->Settings().outPort));
|
||||||
|
m_optionsPage->executablePath->setPath(config->Settings().binPath);
|
||||||
|
m_optionsPage->dataPath->setPath(config->Settings().dataPath);
|
||||||
|
|
||||||
|
m_optionsPage->homeLocation->setChecked(config->Settings().homeLocation);
|
||||||
|
m_optionsPage->homeLocRate->setValue(config->Settings().homeLocRate);
|
||||||
|
|
||||||
|
m_optionsPage->attRaw->setChecked(config->Settings().attRaw);
|
||||||
|
m_optionsPage->attRawRate->setValue(config->Settings().attRawRate);
|
||||||
|
|
||||||
|
m_optionsPage->attActual->setChecked(config->Settings().attActual);
|
||||||
|
m_optionsPage->attActHW->setChecked(config->Settings().attActHW);
|
||||||
|
m_optionsPage->attActSim->setChecked(config->Settings().attActSim);
|
||||||
|
m_optionsPage->attActCalc->setChecked(config->Settings().attActCalc);
|
||||||
|
|
||||||
|
m_optionsPage->sonarAltitude->setChecked(config->Settings().sonarAltitude);
|
||||||
|
m_optionsPage->sonarMaxAlt->setValue(config->Settings().sonarMaxAlt);
|
||||||
|
m_optionsPage->sonarAltRate->setValue(config->Settings().sonarAltRate);
|
||||||
|
|
||||||
|
m_optionsPage->gpsPosition->setChecked(config->Settings().gpsPosition);
|
||||||
|
m_optionsPage->gpsPosRate->setValue(config->Settings().gpsPosRate);
|
||||||
|
|
||||||
|
m_optionsPage->inputCommand->setChecked(config->Settings().inputCommand);
|
||||||
|
m_optionsPage->gcsReciever->setChecked(config->Settings().gcsReciever);
|
||||||
|
m_optionsPage->manualControl->setChecked(config->Settings().manualControl);
|
||||||
|
|
||||||
|
m_optionsPage->manualOutput->setChecked(config->Settings().manualOutput);
|
||||||
|
m_optionsPage->outputRate->setValue(config->Settings().outputRate);
|
||||||
|
|
||||||
|
return optionsPageWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLOptionsPage::apply()
|
||||||
|
{
|
||||||
|
SimulatorSettings settings;
|
||||||
|
int i = m_optionsPage->chooseFlightSimulator->currentIndex();
|
||||||
|
|
||||||
|
settings.simulatorId = m_optionsPage->chooseFlightSimulator->itemData(i).toString();
|
||||||
|
settings.hostAddress = m_optionsPage->hostAddress->text();
|
||||||
|
settings.inPort = m_optionsPage->inputPort->text().toInt();
|
||||||
|
settings.remoteAddress = m_optionsPage->remoteAddress->text();
|
||||||
|
settings.outPort = m_optionsPage->outputPort->text().toInt();
|
||||||
|
settings.binPath = m_optionsPage->executablePath->path();
|
||||||
|
settings.dataPath = m_optionsPage->dataPath->path();
|
||||||
|
|
||||||
|
settings.homeLocation = m_optionsPage->homeLocation->isChecked();
|
||||||
|
settings.homeLocRate = m_optionsPage->homeLocRate->value();
|
||||||
|
|
||||||
|
settings.attRaw = m_optionsPage->attRaw->isChecked();
|
||||||
|
settings.attRawRate = m_optionsPage->attRawRate->value();
|
||||||
|
|
||||||
|
settings.attActual = m_optionsPage->attActual->isChecked();
|
||||||
|
settings.attActHW = m_optionsPage->attActHW->isChecked();
|
||||||
|
settings.attActSim = m_optionsPage->attActSim->isChecked();
|
||||||
|
settings.attActCalc = m_optionsPage->attActCalc->isChecked();
|
||||||
|
|
||||||
|
settings.sonarAltitude = m_optionsPage->sonarAltitude->isChecked();
|
||||||
|
settings.sonarMaxAlt = m_optionsPage->sonarMaxAlt->value();
|
||||||
|
settings.sonarAltRate = m_optionsPage->sonarAltRate->value();
|
||||||
|
|
||||||
|
settings.gpsPosition = m_optionsPage->gpsPosition->isChecked();
|
||||||
|
settings.gpsPosRate = m_optionsPage->gpsPosRate->value();
|
||||||
|
|
||||||
|
settings.inputCommand = m_optionsPage->inputCommand->isChecked();
|
||||||
|
settings.gcsReciever = m_optionsPage->gcsReciever->isChecked();
|
||||||
|
settings.manualControl = m_optionsPage->manualControl->isChecked();
|
||||||
|
|
||||||
|
settings.manualOutput = m_optionsPage->manualOutput->isChecked();
|
||||||
|
settings.outputRate = m_optionsPage->outputRate->value();
|
||||||
|
|
||||||
|
config->setSimulatorSettings(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLOptionsPage::finish()
|
||||||
|
{
|
||||||
|
delete m_optionsPage;
|
||||||
|
}
|
61
ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.h
Normal file
61
ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file hitloptionspage.h
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 HITLV2OPTIONSPAGE_H
|
||||||
|
#define HITLV2OPTIONSPAGE_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 *conf, QObject *parent = 0);
|
||||||
|
|
||||||
|
QWidget *createPage(QWidget *parent);
|
||||||
|
void apply();
|
||||||
|
void finish();
|
||||||
|
bool isDecorated() const { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
HITLConfiguration* config;
|
||||||
|
Ui::HITLOptionsPage* m_optionsPage;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HITLV2OPTIONSPAGE_H
|
639
ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.ui
Normal file
639
ground/openpilotgcs/src/plugins/hitlv2/hitlv2optionspage.ui
Normal file
@ -0,0 +1,639 @@
|
|||||||
|
<?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>403</width>
|
||||||
|
<height>400</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Choose flight simulator:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="chooseFlightSimulator"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Local interface (IP):</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="hostAddress">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>For communication with sim computer via network. Should be the IP address of one of the interfaces of the GCS computer.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="text">
|
||||||
|
<string>Remote interface (IP):</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="remoteAddress">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Only required if running simulator on remote machine. Should be the IP of the machine on which the simulator is running.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Input Port:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QLineEdit" name="inputPort">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>For receiving data from sim</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Output Port:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="3">
|
||||||
|
<widget class="QLineEdit" name="outputPort">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>For sending data to sim</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<property name="fieldGrowthPolicy">
|
||||||
|
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Path executable:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="Utils::PathChooser" name="executablePath" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Data directory:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="Utils::PathChooser" name="dataPath" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Attitude data</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="attRaw">
|
||||||
|
<property name="title">
|
||||||
|
<string>AttitudeRaw (gyro, accels)</string>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>Refresh rate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="attRawRate">
|
||||||
|
<property name="suffix">
|
||||||
|
<string>ms</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="attActual">
|
||||||
|
<property name="title">
|
||||||
|
<string>AttitudeActual</string>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="attActHW">
|
||||||
|
<property name="text">
|
||||||
|
<string>send raw data to board</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="attActSim">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>use values from simulator</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="attActCalc">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>calculate from AttitudeRaw</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<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>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Other data</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="homeLocation">
|
||||||
|
<property name="title">
|
||||||
|
<string>HomeLocation</string>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Refresh rate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="homeLocRate">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>0 - update once, or every N seconds</string>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string>sec</string>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="gpsPosition">
|
||||||
|
<property name="title">
|
||||||
|
<string>GPSPosition</string>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Refresh rate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="gpsPosRate">
|
||||||
|
<property name="suffix">
|
||||||
|
<string>ms</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>2000</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>500</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="sonarAltitude">
|
||||||
|
<property name="title">
|
||||||
|
<string>SonarAltitude</string>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_11">
|
||||||
|
<property name="text">
|
||||||
|
<string>Range detectioon</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QSpinBox" name="sonarMaxAlt">
|
||||||
|
<property name="suffix">
|
||||||
|
<string>m</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_12">
|
||||||
|
<property name="text">
|
||||||
|
<string>Refresh rate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="sonarAltRate">
|
||||||
|
<property name="suffix">
|
||||||
|
<string>ms</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>2000</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="inputCommand">
|
||||||
|
<property name="title">
|
||||||
|
<string>Map command from simulator</string>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="gcsReciever">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>to GCSReciver</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="manualControl">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>to ManualCtrll (not implemented)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="manualOutput">
|
||||||
|
<property name="text">
|
||||||
|
<string>Maximum output rate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="outputRate">
|
||||||
|
<property name="suffix">
|
||||||
|
<string>ms</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</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>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>Utils::PathChooser</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>utils/pathchooser.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>chooseFlightSimulator</tabstop>
|
||||||
|
<tabstop>hostAddress</tabstop>
|
||||||
|
<tabstop>inputPort</tabstop>
|
||||||
|
<tabstop>remoteAddress</tabstop>
|
||||||
|
<tabstop>outputPort</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
70
ground/openpilotgcs/src/plugins/hitlv2/hitlv2plugin.cpp
Normal file
70
ground/openpilotgcs/src/plugins/hitlv2/hitlv2plugin.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file mapplugin.cpp
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 "hitlv2plugin.h"
|
||||||
|
#include "hitlv2factory.h"
|
||||||
|
#include <QtPlugin>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <extensionsystem/pluginmanager.h>
|
||||||
|
|
||||||
|
#include "aerosimrc.h"
|
||||||
|
|
||||||
|
QList<SimulatorCreator* > HITLPlugin::typeSimulators;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
addSimulator(new AeroSimRCSimulatorCreator("ASimRC", "AeroSimRC"));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLPlugin::extensionsInitialized()
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLPlugin::shutdown()
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
Q_EXPORT_PLUGIN(HITLPlugin)
|
||||||
|
|
67
ground/openpilotgcs/src/plugins/hitlv2/hitlv2plugin.h
Normal file
67
ground/openpilotgcs/src/plugins/hitlv2/hitlv2plugin.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file browserplugin.h
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 HITLV2PLUGIN_H
|
||||||
|
#define HITLV2PLUGIN_H
|
||||||
|
|
||||||
|
#include <extensionsystem/iplugin.h>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
#include <simulatorv2.h>
|
||||||
|
|
||||||
|
class HITLFactory;
|
||||||
|
|
||||||
|
class HITLPlugin : public ExtensionSystem::IPlugin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HITLPlugin();
|
||||||
|
~HITLPlugin();
|
||||||
|
|
||||||
|
void extensionsInitialized();
|
||||||
|
bool initialize(const QStringList & arguments, QString * errorString);
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
static void addSimulator(SimulatorCreator* creator)
|
||||||
|
{
|
||||||
|
HITLPlugin::typeSimulators.append(creator);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SimulatorCreator* getSimulatorCreator(const QString classId)
|
||||||
|
{
|
||||||
|
foreach(SimulatorCreator* creator, HITLPlugin::typeSimulators) {
|
||||||
|
if(classId == creator->ClassId())
|
||||||
|
return creator;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<SimulatorCreator* > typeSimulators;
|
||||||
|
|
||||||
|
private:
|
||||||
|
HITLFactory *mf;
|
||||||
|
};
|
||||||
|
#endif /* HITLV2PLUGIN_H */
|
187
ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.cpp
Normal file
187
ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.cpp
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file hitlwidget.cpp
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 "hitlv2widget.h"
|
||||||
|
#include "ui_hitlv2widget.h"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#include "hitlv2plugin.h"
|
||||||
|
#include "simulatorv2.h"
|
||||||
|
#include "uavobjectmanager.h"
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
#include <coreplugin/threadmanager.h>
|
||||||
|
|
||||||
|
QStringList Simulator::instances;
|
||||||
|
|
||||||
|
HITLWidget::HITLWidget(QWidget *parent)
|
||||||
|
: QWidget(parent),
|
||||||
|
simulator(0)
|
||||||
|
{
|
||||||
|
widget = new Ui_HITLWidget();
|
||||||
|
widget->setupUi(this);
|
||||||
|
widget->startButton->setEnabled(true);
|
||||||
|
widget->stopButton->setEnabled(false);
|
||||||
|
|
||||||
|
strAutopilotDisconnected = " AP OFF ";
|
||||||
|
strSimulatorDisconnected = " Sim OFF ";
|
||||||
|
strAutopilotConnected = " AP ON ";
|
||||||
|
// strSimulatorConnected = " Sim ON ";
|
||||||
|
strStyleEnable = "QFrame{background-color: green; color: white}";
|
||||||
|
strStyleDisable = "QFrame{background-color: red; color: grey}";
|
||||||
|
|
||||||
|
widget->apLabel->setText(strAutopilotDisconnected);
|
||||||
|
widget->simLabel->setText(strSimulatorDisconnected);
|
||||||
|
|
||||||
|
connect(widget->startButton, SIGNAL(clicked()), this, SLOT(startButtonClicked()));
|
||||||
|
connect(widget->stopButton, SIGNAL(clicked()), this, SLOT(stopButtonClicked()));
|
||||||
|
connect(widget->buttonClearLog, SIGNAL(clicked()), this, SLOT(buttonClearLogClicked()));
|
||||||
|
}
|
||||||
|
|
||||||
|
HITLWidget::~HITLWidget()
|
||||||
|
{
|
||||||
|
delete widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLWidget::startButtonClicked()
|
||||||
|
{
|
||||||
|
// allow only one instance per simulator
|
||||||
|
if (Simulator::Instances().indexOf(settings.simulatorId) != -1) {
|
||||||
|
widget->textBrowser->append(settings.simulatorId + " alreary started!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!HITLPlugin::typeSimulators.size()) {
|
||||||
|
widget->textBrowser->append("There is no registered simulators, add through HITLPlugin::addSimulator");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop running process if one is active
|
||||||
|
if (simulator) {
|
||||||
|
QMetaObject::invokeMethod(simulator, "onDeleteSimulator", Qt::QueuedConnection);
|
||||||
|
simulator = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.hostAddress == "" || settings.inPort == 0) {
|
||||||
|
widget->textBrowser->append("Before start, set UDP parameters in options page!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimulatorCreator* creator = HITLPlugin::getSimulatorCreator(settings.simulatorId);
|
||||||
|
simulator = creator->createSimulator(settings);
|
||||||
|
simulator->setName(creator->Description());
|
||||||
|
simulator->setSimulatorId(creator->ClassId());
|
||||||
|
|
||||||
|
connect(simulator, SIGNAL(processOutput(QString)), this, SLOT(onProcessOutput(QString)));
|
||||||
|
|
||||||
|
// Setup process
|
||||||
|
onProcessOutput(QString("[%1] Starting %2... ")
|
||||||
|
.arg(QTime::currentTime().toString("hh:mm:ss"))
|
||||||
|
.arg(creator->Description()));
|
||||||
|
|
||||||
|
// Start bridge
|
||||||
|
bool ret = QMetaObject::invokeMethod(simulator, "setupProcess", Qt::QueuedConnection);
|
||||||
|
if (ret) {
|
||||||
|
Simulator::setInstance(settings.simulatorId);
|
||||||
|
|
||||||
|
connect(this, SIGNAL(deleteSimulator()), simulator, SLOT(onDeleteSimulator()), Qt::QueuedConnection);
|
||||||
|
|
||||||
|
widget->startButton->setEnabled(false);
|
||||||
|
widget->stopButton->setEnabled(true);
|
||||||
|
|
||||||
|
connect(simulator, SIGNAL(autopilotConnected()), this, SLOT(onAutopilotConnect()), Qt::QueuedConnection);
|
||||||
|
connect(simulator, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect()), Qt::QueuedConnection);
|
||||||
|
connect(simulator, SIGNAL(simulatorConnected()), this, SLOT(onSimulatorConnect()), Qt::QueuedConnection);
|
||||||
|
connect(simulator, SIGNAL(simulatorDisconnected()), this, SLOT(onSimulatorDisconnect()), Qt::QueuedConnection);
|
||||||
|
|
||||||
|
// Initialize connection status
|
||||||
|
if (simulator->isAutopilotConnected())
|
||||||
|
onAutopilotConnect();
|
||||||
|
else
|
||||||
|
onAutopilotDisconnect();
|
||||||
|
|
||||||
|
if (simulator->isSimulatorConnected())
|
||||||
|
onSimulatorConnect();
|
||||||
|
else
|
||||||
|
onSimulatorDisconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLWidget::stopButtonClicked()
|
||||||
|
{
|
||||||
|
if (simulator)
|
||||||
|
widget->textBrowser->append(QString("[%1] Terminate %2 ")
|
||||||
|
.arg(QTime::currentTime().toString("hh:mm:ss"))
|
||||||
|
.arg(simulator->Name()));
|
||||||
|
|
||||||
|
widget->startButton->setEnabled(true);
|
||||||
|
widget->stopButton->setEnabled(false);
|
||||||
|
widget->apLabel->setStyleSheet(QString::fromUtf8("QFrame{background-color: transparent; color: white}"));
|
||||||
|
widget->simLabel->setStyleSheet(QString::fromUtf8("QFrame{background-color: transparent; color: white}"));
|
||||||
|
widget->apLabel->setText(strAutopilotDisconnected);
|
||||||
|
widget->simLabel->setText(strSimulatorDisconnected);
|
||||||
|
if (simulator) {
|
||||||
|
QMetaObject::invokeMethod(simulator, "onDeleteSimulator", Qt::QueuedConnection);
|
||||||
|
simulator = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLWidget::buttonClearLogClicked()
|
||||||
|
{
|
||||||
|
widget->textBrowser->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLWidget::onProcessOutput(QString text)
|
||||||
|
{
|
||||||
|
widget->textBrowser->append(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLWidget::onAutopilotConnect()
|
||||||
|
{
|
||||||
|
widget->apLabel->setStyleSheet(strStyleEnable);
|
||||||
|
widget->apLabel->setText(strAutopilotConnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLWidget::onAutopilotDisconnect()
|
||||||
|
{
|
||||||
|
widget->apLabel->setStyleSheet(strStyleDisable);
|
||||||
|
widget->apLabel->setText(strAutopilotDisconnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLWidget::onSimulatorConnect()
|
||||||
|
{
|
||||||
|
widget->simLabel->setStyleSheet(strStyleEnable);
|
||||||
|
widget->simLabel->setText(" " + simulator->Name() + " ON ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void HITLWidget::onSimulatorDisconnect()
|
||||||
|
{
|
||||||
|
widget->simLabel->setStyleSheet(strStyleDisable);
|
||||||
|
widget->simLabel->setText(" " + simulator->Name() + " OFF ");
|
||||||
|
}
|
72
ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.h
Normal file
72
ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file hitlwidget.h
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 HITLV2WIDGET_H
|
||||||
|
#define HITLV2WIDGET_H
|
||||||
|
|
||||||
|
#include <QtGui/QWidget>
|
||||||
|
#include <QProcess>
|
||||||
|
#include "simulatorv2.h"
|
||||||
|
|
||||||
|
class Ui_HITLWidget;
|
||||||
|
|
||||||
|
class HITLWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
HITLWidget(QWidget *parent = 0);
|
||||||
|
~HITLWidget();
|
||||||
|
|
||||||
|
void setSettingParameters(const SimulatorSettings& params) { settings = params; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void deleteSimulator();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void startButtonClicked();
|
||||||
|
void stopButtonClicked();
|
||||||
|
void buttonClearLogClicked();
|
||||||
|
void onProcessOutput(QString text);
|
||||||
|
void onAutopilotConnect();
|
||||||
|
void onAutopilotDisconnect();
|
||||||
|
void onSimulatorConnect();
|
||||||
|
void onSimulatorDisconnect();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui_HITLWidget* widget;
|
||||||
|
Simulator* simulator;
|
||||||
|
SimulatorSettings settings;
|
||||||
|
|
||||||
|
QString strAutopilotDisconnected;
|
||||||
|
QString strSimulatorDisconnected;
|
||||||
|
QString strAutopilotConnected;
|
||||||
|
// QString strSimulatorConnected;
|
||||||
|
QString strStyleEnable;
|
||||||
|
QString strStyleDisable;
|
||||||
|
};
|
||||||
|
#endif /* HITLV2WIDGET_H */
|
314
ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.ui
Normal file
314
ground/openpilotgcs/src/plugins/hitlv2/hitlv2widget.ui
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
<?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>477</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">
|
||||||
|
|
||||||
|
QScrollBar:vertical {
|
||||||
|
border: 1px solid grey;
|
||||||
|
background: grey;
|
||||||
|
margin: 22px 0 22px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar:vertical:disabled {
|
||||||
|
border: 1px solid grey;
|
||||||
|
|
||||||
|
background-color: grey;
|
||||||
|
margin: 22px 0 22px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical {
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(120, 120, 255, 255), stop:1 rgba(80, 80, 160, 255));
|
||||||
|
min-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical:disabled{
|
||||||
|
background-color: grey;
|
||||||
|
min-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical:pressed {
|
||||||
|
|
||||||
|
background-color: rgb(85, 85, 255);
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(170, 170, 255, 255), stop:1 rgba(80, 80, 160, 255));
|
||||||
|
|
||||||
|
min-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:vertical {
|
||||||
|
border: 1px solid black;
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(48, 48, 48, 255), stop:1 rgba(120, 120, 120, 255));
|
||||||
|
height: 20px;
|
||||||
|
subcontrol-position: bottom;
|
||||||
|
subcontrol-origin: margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:vertical:disabled {
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(100, 100, 100, 255));
|
||||||
|
border: 1px solid grey;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::sub-line:vertical:disabled {
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(100, 100, 100, 255));
|
||||||
|
border: 1px solid grey;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:vertical:pressed {
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(255, 255, 255, 200), stop:1 rgba(180, 180, 180, 200));
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::sub-line:vertical:pressed {
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(255, 255, 255, 200), stop:1 rgba(180, 180, 180, 200));
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::sub-line:vertical {
|
||||||
|
border: 1px solid black;
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(48, 48, 48, 255), stop:1 rgba(120, 120, 120, 255));
|
||||||
|
height: 20px;
|
||||||
|
subcontrol-position: top;
|
||||||
|
subcontrol-origin: margin;
|
||||||
|
}
|
||||||
|
QScrollBar::down-arrow:vertical {
|
||||||
|
|
||||||
|
image: url(:/hitlnew/images/arrow-down2.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::up-arrow:vertical {
|
||||||
|
image: url(:/hitlnew/images/arrow-up2.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QPushButton {
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(110, 110, 110, 255), stop:1 rgba(71, 71, 71, 255));
|
||||||
|
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
border: 1px solid black;
|
||||||
|
width: 66px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:disabled {
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(120, 120, 120, 255));
|
||||||
|
color: rgb(194, 194, 194);
|
||||||
|
border: 1px solid gray;
|
||||||
|
width: 66px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:hover {
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(255, 255, 255, 200), stop:1 rgba(180, 180, 180, 200));
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
QPushButton:pressed {
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(48, 48, 48, 255), stop:1 rgba(120, 120, 120, 255));
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:checked {
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(48, 48, 48, 255), stop:1 rgba(120, 120, 120, 255));
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
border: 0px;
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="margin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="frame">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">
|
||||||
|
|
||||||
|
QFrame{
|
||||||
|
background-color: qlineargradient(spread:pad, x1:0.5, y1:0, x2:0.5, y2:1, stop:0 rgba(110, 110, 110, 255), stop:1 rgba(71, 71, 71, 255));
|
||||||
|
color: rgba(0, 0, 0, 128);
|
||||||
|
}
|
||||||
|
</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMaximumSize</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="startButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Request update</string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Start</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="stopButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Send update</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Stop</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="apLabel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>22</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="layoutDirection">
|
||||||
|
<enum>Qt::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">color: rgb(255, 255, 255);</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>AP OFF</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="simLabel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>22</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">color: rgb(255, 255, 255);</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Sim OFF</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="buttonClearLog">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear Log</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTextEdit" name="textBrowser">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QTextEdit {
|
||||||
|
background-color: white;
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
341
ground/openpilotgcs/src/plugins/hitlv2/simulatorv2.cpp
Normal file
341
ground/openpilotgcs/src/plugins/hitlv2/simulatorv2.cpp
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file simulator.cpp
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 "simulatorv2.h"
|
||||||
|
#include <extensionsystem/pluginmanager.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
#include <coreplugin/threadmanager.h>
|
||||||
|
|
||||||
|
volatile bool Simulator::isStarted = false;
|
||||||
|
|
||||||
|
const float Simulator::GEE = 9.81;
|
||||||
|
const float Simulator::FT2M = 0.3048;
|
||||||
|
const float Simulator::KT2MPS = 0.514444444;
|
||||||
|
const float Simulator::INHG2KPA = 3.386;
|
||||||
|
const float Simulator::FPS2CMPS = 30.48;
|
||||||
|
const float Simulator::DEG2RAD = (M_PI/180.0);
|
||||||
|
const float Simulator::RAD2DEG = (180.0/M_PI);
|
||||||
|
|
||||||
|
|
||||||
|
Simulator::Simulator(const SimulatorSettings& params) :
|
||||||
|
inSocket(NULL),
|
||||||
|
outSocket(NULL),
|
||||||
|
settings(params),
|
||||||
|
updatePeriod(50),
|
||||||
|
simTimeout(2000),
|
||||||
|
autopilotConnectionStatus(false),
|
||||||
|
simConnectionStatus(false),
|
||||||
|
txTimer(NULL),
|
||||||
|
simTimer(NULL),
|
||||||
|
name("")
|
||||||
|
{
|
||||||
|
// move to thread
|
||||||
|
moveToThread(Core::ICore::instance()->threadManager()->getRealTimeThread());
|
||||||
|
connect(this, SIGNAL(myStart()), this, SLOT(onStart()), Qt::QueuedConnection);
|
||||||
|
emit myStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
Simulator::~Simulator()
|
||||||
|
{
|
||||||
|
// qDebug() << "Simulator::~Simulator";
|
||||||
|
if (inSocket) {
|
||||||
|
delete inSocket;
|
||||||
|
inSocket = NULL;
|
||||||
|
}
|
||||||
|
if (outSocket) {
|
||||||
|
delete outSocket;
|
||||||
|
outSocket = NULL;
|
||||||
|
}
|
||||||
|
if (txTimer) {
|
||||||
|
delete txTimer;
|
||||||
|
txTimer = NULL;
|
||||||
|
}
|
||||||
|
if (simTimer) {
|
||||||
|
delete simTimer;
|
||||||
|
simTimer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::onDeleteSimulator(void)
|
||||||
|
{
|
||||||
|
// qDebug() << "Simulator::onDeleteSimulator";
|
||||||
|
resetAllObjects();
|
||||||
|
|
||||||
|
Simulator::setStarted(false);
|
||||||
|
Simulator::Instances().removeOne(simulatorId);
|
||||||
|
|
||||||
|
disconnect(this);
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::onStart()
|
||||||
|
{
|
||||||
|
// qDebug() << "Simulator::onStart";
|
||||||
|
QMutexLocker locker(&lock);
|
||||||
|
|
||||||
|
// Get required UAVObjects
|
||||||
|
ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
|
||||||
|
UAVObjectManager* objManager = pm->getObject<UAVObjectManager>();
|
||||||
|
|
||||||
|
// actDesired = ActuatorDesired::GetInstance(objManager);
|
||||||
|
// manCtrlCommand = ManualControlCommand::GetInstance(objManager);
|
||||||
|
// velActual = VelocityActual::GetInstance(objManager);
|
||||||
|
// posActual = PositionActual::GetInstance(objManager);
|
||||||
|
// altActual = BaroAltitude::GetInstance(objManager);
|
||||||
|
// camDesired = CameraDesired::GetInstance(objManager);
|
||||||
|
// acsDesired = AccessoryDesired::GetInstance(objManager);
|
||||||
|
posHome = HomeLocation::GetInstance(objManager);
|
||||||
|
accels = Accels::GetInstance(objManager);
|
||||||
|
gyros = Gyros::GetInstance(objManager);
|
||||||
|
attActual = AttitudeActual::GetInstance(objManager);
|
||||||
|
gpsPosition = GPSPosition::GetInstance(objManager);
|
||||||
|
flightStatus = FlightStatus::GetInstance(objManager);
|
||||||
|
gcsReceiver = GCSReceiver::GetInstance(objManager);
|
||||||
|
actCommand = ActuatorCommand::GetInstance(objManager);
|
||||||
|
attSettings = AttitudeSettings::GetInstance(objManager);
|
||||||
|
sonarAlt = SonarAltitude::GetInstance(objManager);
|
||||||
|
|
||||||
|
telStats = GCSTelemetryStats::GetInstance(objManager);
|
||||||
|
|
||||||
|
// Listen to autopilot connection events
|
||||||
|
TelemetryManager* telMngr = pm->getObject<TelemetryManager>();
|
||||||
|
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
|
||||||
|
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
|
||||||
|
|
||||||
|
// If already connect setup autopilot
|
||||||
|
GCSTelemetryStats::DataFields stats = telStats->getData();
|
||||||
|
if (stats.Status == GCSTelemetryStats::STATUS_CONNECTED)
|
||||||
|
onAutopilotConnect();
|
||||||
|
|
||||||
|
emit processOutput("Local interface: " + settings.hostAddress + ":" + \
|
||||||
|
QString::number(settings.inPort) + "\n" + \
|
||||||
|
"Remote interface: " + settings.remoteAddress + ":" + \
|
||||||
|
QString::number(settings.outPort) + "\n");
|
||||||
|
|
||||||
|
inSocket = new QUdpSocket();
|
||||||
|
outSocket = new QUdpSocket();
|
||||||
|
setupUdpPorts(settings.hostAddress, settings.inPort, settings.outPort);
|
||||||
|
|
||||||
|
connect(inSocket, SIGNAL(readyRead()), this, SLOT(receiveUpdate())/*, Qt::DirectConnection*/);
|
||||||
|
|
||||||
|
// Setup transmit timer
|
||||||
|
if (settings.manualOutput) {
|
||||||
|
txTimer = new QTimer();
|
||||||
|
connect(txTimer, SIGNAL(timeout()), this, SLOT(transmitUpdate())/*, Qt::DirectConnection*/);
|
||||||
|
txTimer->setInterval(settings.outputRate);
|
||||||
|
txTimer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup simulator connection timer
|
||||||
|
simTimer = new QTimer();
|
||||||
|
connect(simTimer, SIGNAL(timeout()), this, SLOT(onSimulatorConnectionTimeout())/*, Qt::DirectConnection*/);
|
||||||
|
simTimer->setInterval(simTimeout);
|
||||||
|
simTimer->start();
|
||||||
|
|
||||||
|
#ifdef DBG_TIMERS
|
||||||
|
timeRX = QTime();
|
||||||
|
timeRX.start();
|
||||||
|
timeTX = QTime();
|
||||||
|
timeTX.start();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
setupObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::receiveUpdate()
|
||||||
|
{
|
||||||
|
// Update connection timer and status
|
||||||
|
simTimer->start();
|
||||||
|
if (!simConnectionStatus) {
|
||||||
|
simConnectionStatus = true;
|
||||||
|
emit simulatorConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process data
|
||||||
|
while (inSocket->hasPendingDatagrams()) {
|
||||||
|
// Receive datagram
|
||||||
|
QByteArray datagram;
|
||||||
|
datagram.resize(inSocket->pendingDatagramSize());
|
||||||
|
QHostAddress sender;
|
||||||
|
quint16 senderPort;
|
||||||
|
inSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
|
||||||
|
// Process incomming data
|
||||||
|
processUpdate(datagram);
|
||||||
|
}
|
||||||
|
if (!settings.manualOutput)
|
||||||
|
transmitUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::setupObjects()
|
||||||
|
{
|
||||||
|
if (settings.gcsReciever) {
|
||||||
|
setupInputObject(actCommand, settings.outputRate);
|
||||||
|
setupOutputObject(gcsReceiver);
|
||||||
|
} else if (settings.manualControl) {
|
||||||
|
// setupInputObject(actDesired);
|
||||||
|
// setupInputObject(camDesired);
|
||||||
|
// setupInputObject(acsDesired);
|
||||||
|
// setupOutputObject(manCtrlCommand);
|
||||||
|
qDebug() << "ManualControlCommand not implemented yet";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.homeLocation)
|
||||||
|
setupOutputObject(posHome);
|
||||||
|
|
||||||
|
if (settings.sonarAltitude)
|
||||||
|
setupOutputObject(sonarAlt);
|
||||||
|
|
||||||
|
if (settings.gpsPosition)
|
||||||
|
setupOutputObject(gpsPosition);
|
||||||
|
|
||||||
|
if (settings.attRaw || settings.attActual) {
|
||||||
|
setupOutputObject(accels);
|
||||||
|
setupOutputObject(gyros);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.attActual && !settings.attActHW)
|
||||||
|
setupOutputObject(attActual);
|
||||||
|
else
|
||||||
|
setupWatchedObject(attActual);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::resetAllObjects()
|
||||||
|
{
|
||||||
|
setupDefaultObject(posHome);
|
||||||
|
setupDefaultObject(accels);
|
||||||
|
setupDefaultObject(gyros);
|
||||||
|
setupDefaultObject(attActual);
|
||||||
|
setupDefaultObject(gpsPosition);
|
||||||
|
setupDefaultObject(gcsReceiver);
|
||||||
|
setupDefaultObject(actCommand);
|
||||||
|
setupDefaultObject(sonarAlt);
|
||||||
|
// setupDefaultObject(manCtrlCommand);
|
||||||
|
// setupDefaultObject(actDesired);
|
||||||
|
// setupDefaultObject(camDesired);
|
||||||
|
// setupDefaultObject(acsDesired);
|
||||||
|
// setupDefaultObject(altActual);
|
||||||
|
// setupDefaultObject(posActual);
|
||||||
|
// setupDefaultObject(velActual);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::setupInputObject(UAVObject* obj, quint32 updateRate)
|
||||||
|
{
|
||||||
|
UAVObject::Metadata mdata;
|
||||||
|
mdata = obj->getDefaultMetadata();
|
||||||
|
|
||||||
|
UAVObject::SetGcsAccess(mdata, UAVObject::ACCESS_READONLY);
|
||||||
|
UAVObject::SetGcsTelemetryAcked(mdata, false);
|
||||||
|
UAVObject::SetGcsTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_MANUAL);
|
||||||
|
mdata.gcsTelemetryUpdatePeriod = 0;
|
||||||
|
|
||||||
|
UAVObject::SetFlightAccess(mdata, UAVObject::ACCESS_READWRITE);
|
||||||
|
UAVObject::SetFlightTelemetryAcked(mdata, false);
|
||||||
|
|
||||||
|
if (settings.manualOutput) {
|
||||||
|
UAVObject::SetFlightTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_PERIODIC);
|
||||||
|
mdata.flightTelemetryUpdatePeriod = updateRate;
|
||||||
|
} else {
|
||||||
|
UAVObject::SetFlightTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_ONCHANGE);
|
||||||
|
mdata.flightTelemetryUpdatePeriod = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->setMetadata(mdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::setupWatchedObject(UAVObject *obj)
|
||||||
|
{
|
||||||
|
UAVObject::Metadata mdata;
|
||||||
|
mdata = obj->getDefaultMetadata();
|
||||||
|
|
||||||
|
UAVObject::SetGcsAccess(mdata, UAVObject::ACCESS_READONLY);
|
||||||
|
UAVObject::SetGcsTelemetryAcked(mdata, false);
|
||||||
|
UAVObject::SetGcsTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_MANUAL);
|
||||||
|
mdata.gcsTelemetryUpdatePeriod = 0;
|
||||||
|
|
||||||
|
UAVObject::SetFlightAccess(mdata, UAVObject::ACCESS_READWRITE);
|
||||||
|
UAVObject::SetFlightTelemetryAcked(mdata, false);
|
||||||
|
UAVObject::SetFlightTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_PERIODIC);
|
||||||
|
mdata.flightTelemetryUpdatePeriod = 100;
|
||||||
|
|
||||||
|
obj->setMetadata(mdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::setupOutputObject(UAVObject* obj)
|
||||||
|
{
|
||||||
|
UAVObject::Metadata mdata;
|
||||||
|
mdata = obj->getDefaultMetadata();
|
||||||
|
|
||||||
|
UAVObject::SetGcsAccess(mdata, UAVObject::ACCESS_READWRITE);
|
||||||
|
UAVObject::SetGcsTelemetryAcked(mdata, false);
|
||||||
|
UAVObject::SetGcsTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_ONCHANGE);
|
||||||
|
mdata.gcsTelemetryUpdatePeriod = 0;
|
||||||
|
|
||||||
|
UAVObject::SetFlightAccess(mdata, UAVObject::ACCESS_READONLY);
|
||||||
|
UAVObject::SetFlightTelemetryAcked(mdata, false);
|
||||||
|
UAVObject::SetFlightTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_MANUAL);
|
||||||
|
mdata.flightTelemetryUpdatePeriod = 0;
|
||||||
|
|
||||||
|
obj->setMetadata(mdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::setupDefaultObject(UAVObject *obj)
|
||||||
|
{
|
||||||
|
UAVObject::Metadata mdata;
|
||||||
|
mdata = obj->getDefaultMetadata();
|
||||||
|
|
||||||
|
obj->setMetadata(mdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::onAutopilotConnect()
|
||||||
|
{
|
||||||
|
autopilotConnectionStatus = true;
|
||||||
|
emit autopilotConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::onAutopilotDisconnect()
|
||||||
|
{
|
||||||
|
autopilotConnectionStatus = false;
|
||||||
|
emit autopilotDisconnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::onSimulatorConnectionTimeout()
|
||||||
|
{
|
||||||
|
if (simConnectionStatus) {
|
||||||
|
simConnectionStatus = false;
|
||||||
|
emit simulatorDisconnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::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();
|
||||||
|
}
|
||||||
|
|
222
ground/openpilotgcs/src/plugins/hitlv2/simulatorv2.h
Normal file
222
ground/openpilotgcs/src/plugins/hitlv2/simulatorv2.h
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file simulator.h
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @addtogroup GCSPlugins GCS Plugins
|
||||||
|
* @{
|
||||||
|
* @addtogroup HITLPlugin HITL Plugin
|
||||||
|
* @{
|
||||||
|
* @brief The Hardware In The Loop plugin
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* 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 ISIMULATORV2_H
|
||||||
|
#define ISIMULATORV2_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QUdpSocket>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QScopedPointer>
|
||||||
|
#include <qmath.h>
|
||||||
|
#include "uavtalk/telemetrymanager.h"
|
||||||
|
#include "uavobjectmanager.h"
|
||||||
|
#include "homelocation.h"
|
||||||
|
#include "accels.h"
|
||||||
|
#include "gyros.h"
|
||||||
|
#include "attitudeactual.h"
|
||||||
|
#include "gpsposition.h"
|
||||||
|
#include "flightstatus.h"
|
||||||
|
#include "gcsreceiver.h"
|
||||||
|
#include "actuatorcommand.h"
|
||||||
|
#include "gcstelemetrystats.h"
|
||||||
|
#include "attitudesettings.h"
|
||||||
|
#include "sonaraltitude.h"
|
||||||
|
|
||||||
|
//#define DBG_TIMERS
|
||||||
|
#undef DBG_TIMERS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* just imagine this was a class without methods and all public properties
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _CONNECTION
|
||||||
|
{
|
||||||
|
QString simulatorId;
|
||||||
|
QString hostAddress;
|
||||||
|
int inPort;
|
||||||
|
QString remoteAddress;
|
||||||
|
int outPort;
|
||||||
|
QString binPath;
|
||||||
|
QString dataPath;
|
||||||
|
|
||||||
|
bool homeLocation;
|
||||||
|
quint16 homeLocRate;
|
||||||
|
|
||||||
|
bool attRaw;
|
||||||
|
quint8 attRawRate;
|
||||||
|
|
||||||
|
bool attActual;
|
||||||
|
bool attActHW;
|
||||||
|
bool attActSim;
|
||||||
|
bool attActCalc;
|
||||||
|
|
||||||
|
bool sonarAltitude;
|
||||||
|
float sonarMaxAlt;
|
||||||
|
quint16 sonarAltRate;
|
||||||
|
|
||||||
|
bool gpsPosition;
|
||||||
|
quint16 gpsPosRate;
|
||||||
|
|
||||||
|
bool inputCommand;
|
||||||
|
bool gcsReciever;
|
||||||
|
bool manualControl;
|
||||||
|
bool manualOutput;
|
||||||
|
quint8 outputRate;
|
||||||
|
|
||||||
|
} SimulatorSettings;
|
||||||
|
|
||||||
|
class Simulator : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Simulator(const SimulatorSettings& params);
|
||||||
|
virtual ~Simulator();
|
||||||
|
|
||||||
|
bool isAutopilotConnected() const { return autopilotConnectionStatus; }
|
||||||
|
bool isSimulatorConnected() const { return simConnectionStatus; }
|
||||||
|
|
||||||
|
QString Name() const { return name; }
|
||||||
|
void setName(QString str) { name = str; }
|
||||||
|
|
||||||
|
QString SimulatorId() const { return simulatorId; }
|
||||||
|
void setSimulatorId(QString str) { simulatorId = str; }
|
||||||
|
|
||||||
|
static bool IsStarted() { return isStarted; }
|
||||||
|
static void setStarted(bool val) { isStarted = val; }
|
||||||
|
|
||||||
|
static QStringList& Instances() { return Simulator::instances; }
|
||||||
|
static void setInstance(const QString& str) { Simulator::instances.append(str); }
|
||||||
|
|
||||||
|
virtual void stopProcess() {}
|
||||||
|
virtual void setupUdpPorts(const QString& host, int inPort, int outPort) { Q_UNUSED(host) Q_UNUSED(inPort) Q_UNUSED(outPort)}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void processOutput(QString str);
|
||||||
|
void autopilotConnected();
|
||||||
|
void autopilotDisconnected();
|
||||||
|
void simulatorConnected();
|
||||||
|
void simulatorDisconnected();
|
||||||
|
void myStart();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
Q_INVOKABLE virtual bool setupProcess() { return true; }
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onStart();
|
||||||
|
void receiveUpdate();
|
||||||
|
void onAutopilotConnect();
|
||||||
|
void onAutopilotDisconnect();
|
||||||
|
void onSimulatorConnectionTimeout();
|
||||||
|
void telStatsUpdated(UAVObject* obj);
|
||||||
|
Q_INVOKABLE void onDeleteSimulator(void);
|
||||||
|
|
||||||
|
virtual void transmitUpdate() = 0;
|
||||||
|
virtual void processUpdate(const QByteArray& data) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static const float GEE;
|
||||||
|
static const float FT2M;
|
||||||
|
static const float KT2MPS;
|
||||||
|
static const float INHG2KPA;
|
||||||
|
static const float FPS2CMPS;
|
||||||
|
static const float DEG2RAD;
|
||||||
|
static const float RAD2DEG;
|
||||||
|
|
||||||
|
#ifdef DBG_TIMERS
|
||||||
|
QTime timeRX;
|
||||||
|
QTime timeTX;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QUdpSocket* inSocket;
|
||||||
|
QUdpSocket* outSocket;
|
||||||
|
|
||||||
|
// ActuatorDesired* actDesired;
|
||||||
|
// ManualControlCommand* manCtrlCommand;
|
||||||
|
// VelocityActual* velActual;
|
||||||
|
// PositionActual* posActual;
|
||||||
|
// BaroAltitude* altActual;
|
||||||
|
// CameraDesired *camDesired;
|
||||||
|
// AccessoryDesired *acsDesired;
|
||||||
|
Accels *accels;
|
||||||
|
Gyros *gyros;
|
||||||
|
AttitudeActual *attActual;
|
||||||
|
HomeLocation *posHome;
|
||||||
|
FlightStatus *flightStatus;
|
||||||
|
GPSPosition *gpsPosition;
|
||||||
|
GCSReceiver *gcsReceiver;
|
||||||
|
ActuatorCommand *actCommand;
|
||||||
|
AttitudeSettings *attSettings;
|
||||||
|
SonarAltitude *sonarAlt;
|
||||||
|
|
||||||
|
GCSTelemetryStats* telStats;
|
||||||
|
SimulatorSettings settings;
|
||||||
|
|
||||||
|
QMutex lock;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int updatePeriod;
|
||||||
|
int simTimeout;
|
||||||
|
volatile bool autopilotConnectionStatus;
|
||||||
|
volatile bool simConnectionStatus;
|
||||||
|
QTimer* txTimer;
|
||||||
|
QTimer* simTimer;
|
||||||
|
QString name;
|
||||||
|
QString simulatorId;
|
||||||
|
volatile static bool isStarted;
|
||||||
|
static QStringList instances;
|
||||||
|
|
||||||
|
void setupObjects();
|
||||||
|
void resetAllObjects();
|
||||||
|
void setupInputObject(UAVObject* obj, quint32 updateRate);
|
||||||
|
void setupOutputObject(UAVObject* obj);
|
||||||
|
void setupWatchedObject(UAVObject *obj);
|
||||||
|
void setupDefaultObject(UAVObject *obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SimulatorCreator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SimulatorCreator(QString id, QString descr) :
|
||||||
|
classId(id),
|
||||||
|
description(descr)
|
||||||
|
{}
|
||||||
|
virtual ~SimulatorCreator() {}
|
||||||
|
|
||||||
|
QString ClassId() const { return classId; }
|
||||||
|
QString Description() const { return description; }
|
||||||
|
|
||||||
|
virtual Simulator* createSimulator(const SimulatorSettings& params) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString classId;
|
||||||
|
QString description;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ISIMULATORV2_H
|
@ -147,6 +147,13 @@ plugin_hitlnew.depends += plugin_uavobjects
|
|||||||
plugin_hitlnew.depends += plugin_uavtalk
|
plugin_hitlnew.depends += plugin_uavtalk
|
||||||
SUBDIRS += plugin_hitlnew
|
SUBDIRS += plugin_hitlnew
|
||||||
|
|
||||||
|
#HITLNEW Simulation gadget v2
|
||||||
|
plugin_hitl_v2.subdir = hitlv2
|
||||||
|
plugin_hitl_v2.depends = plugin_coreplugin
|
||||||
|
plugin_hitl_v2.depends += plugin_uavobjects
|
||||||
|
plugin_hitl_v2.depends += plugin_uavtalk
|
||||||
|
SUBDIRS += plugin_hitl_v2
|
||||||
|
|
||||||
# Export and Import GCS Configuration
|
# Export and Import GCS Configuration
|
||||||
plugin_importexport.subdir = importexport
|
plugin_importexport.subdir = importexport
|
||||||
plugin_importexport.depends = plugin_coreplugin
|
plugin_importexport.depends = plugin_coreplugin
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<xml>
|
<xml>
|
||||||
<object name="GCSReceiver" singleinstance="true" settings="false">
|
<object name="GCSReceiver" singleinstance="true" settings="false">
|
||||||
<description>A receiver channel group carried over the telemetry link.</description>
|
<description>A receiver channel group carried over the telemetry link.</description>
|
||||||
<field name="Channel" units="us" type="uint16" elements="6"/>
|
<field name="Channel" units="us" type="uint16" elements="8"/>
|
||||||
<access gcs="readwrite" flight="readwrite"/>
|
<access gcs="readwrite" flight="readonly"/>
|
||||||
<telemetrygcs acked="false" updatemode="onchange" period="0"/>
|
<telemetrygcs acked="false" updatemode="onchange" period="0"/>
|
||||||
<telemetryflight acked="false" updatemode="onchange" period="0"/>
|
<telemetryflight acked="false" updatemode="onchange" period="0"/>
|
||||||
<logging updatemode="manual" period="0"/>
|
<logging updatemode="manual" period="0"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user