1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +01:00

Merge branch 'next' into revo

Conflicts:
	flight/Modules/GPS/GPS.c
	shared/uavobjectdefinition/manualcontrolsettings.xml
	shared/uavobjectdefinition/systemalarms.xml
This commit is contained in:
James Cotton 2012-08-12 14:38:38 -05:00
commit 75db0fcb35
75 changed files with 3780 additions and 467 deletions

View File

@ -1,5 +1,13 @@
Short summary of changes. For a complete list see the git log.
2012-07-20
AeroSimRC simulator plugin is now included into the Windows distribution
(will be installed into .../OpenPilot/misc/AeroSIM-RC directory). Still
being an experimental development tool, it could be used to play with
HITL version 2. Other platforms include udp_test utility which can be
used to check the connectivity with AeroSimRC plugin running on Windows
machine.
2012-07-10
On Windows the installation mode was changed from per-user to per-machine
(for all users) installation. It is recommended to completely uninstall

View File

@ -94,8 +94,8 @@
/* Task stack sizes */
#define PIOS_ACTUATOR_STACK_SIZE 1020
#define PIOS_MANUAL_STACK_SIZE 724
#define PIOS_SYSTEM_STACK_SIZE 460
#define PIOS_MANUAL_STACK_SIZE 800
#define PIOS_SYSTEM_STACK_SIZE 660
#define PIOS_STABILIZATION_STACK_SIZE 524
#define PIOS_TELEM_STACK_SIZE 500
#define PIOS_EVENTDISPATCHER_STACK_SIZE 130

View File

@ -33,7 +33,6 @@
#define PIOS_INCLUDE_SYS
#define PIOS_INCLUDE_DELAY
#define PIOS_INCLUDE_LED
#define PIOS_INCLUDE_SDCARD
#define PIOS_INCLUDE_FREERTOS
#define PIOS_INCLUDE_COM
#define PIOS_INCLUDE_UDP

View File

@ -242,7 +242,7 @@ int WMM_GetMagVector(float Lat, float Lon, float AltEllipsoid, uint16_t Month, u
{
CoordGeodetic->lambda = Lon;
CoordGeodetic->phi = Lat;
CoordGeodetic->HeightAboveEllipsoid = AltEllipsoid;
CoordGeodetic->HeightAboveEllipsoid = AltEllipsoid/1000.0; // convert to km
// Convert from geodeitic to Spherical Equations: 17-18, WMM Technical report
if (WMM_GeodeticToSpherical(CoordGeodetic, CoordSpherical) < 0)

View File

@ -375,6 +375,10 @@ static int32_t updateSensorsCC3D(AccelsData * accelsData, GyrosData * gyrosData)
if(xQueueReceive(queue, (void *) &mpu6000_data, SENSOR_PERIOD) == errQUEUE_EMPTY)
return -1; // Error, no data
// Do not read raw sensor data in simulation mode
if (GyrosReadOnly() || AccelsReadOnly())
return 0;
gyros[0] = -mpu6000_data.gyro_y * PIOS_MPU6000_GetScale();
gyros[1] = -mpu6000_data.gyro_x * PIOS_MPU6000_GetScale();
gyros[2] = -mpu6000_data.gyro_z * PIOS_MPU6000_GetScale();

View File

@ -73,6 +73,7 @@
static uint32_t idleCounter;
static uint32_t idleCounterClear;
static xTaskHandle systemTaskHandle;
static xQueueHandle objectPersistenceQueue;
static bool stackOverflow;
static bool mallocFailed;
@ -122,6 +123,10 @@ int32_t SystemModInitialize(void)
WatchdogStatusInitialize();
#endif
objectPersistenceQueue = xQueueCreate(1, sizeof(UAVObjEvent));
if (objectPersistenceQueue == NULL)
return -1;
SystemModStart();
return 0;
@ -133,8 +138,6 @@ MODULE_INITCALL(SystemModInitialize, 0)
*/
static void systemTask(void *parameters)
{
portTickType lastSysTime;
/* create all modules thread */
MODULE_TASKCREATE_ALL;
@ -154,10 +157,9 @@ static void systemTask(void *parameters)
// Initialize vars
idleCounter = 0;
idleCounterClear = 0;
lastSysTime = xTaskGetTickCount();
// Listen for SettingPersistance object updates, connect a callback function
ObjectPersistenceConnectCallback(&objectUpdatedCb);
ObjectPersistenceConnectQueue(objectPersistenceQueue);
// Main system loop
while (1) {
@ -193,11 +195,14 @@ static void systemTask(void *parameters)
FlightStatusData flightStatus;
FlightStatusGet(&flightStatus);
// Wait until next period
if(flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED) {
vTaskDelayUntil(&lastSysTime, SYSTEM_UPDATE_PERIOD_MS / portTICK_RATE_MS / (LED_BLINK_RATE_HZ * 2) );
} else {
vTaskDelayUntil(&lastSysTime, SYSTEM_UPDATE_PERIOD_MS / portTICK_RATE_MS);
UAVObjEvent ev;
int delayTime = flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED ?
SYSTEM_UPDATE_PERIOD_MS / portTICK_RATE_MS / (LED_BLINK_RATE_HZ * 2) :
SYSTEM_UPDATE_PERIOD_MS / portTICK_RATE_MS;
if(xQueueReceive(objectPersistenceQueue, &ev, delayTime) == pdTRUE) {
// If object persistence is updated call the callback
objectUpdatedCb(&ev);
}
}
}

View File

@ -33,7 +33,6 @@
#define PIOS_INCLUDE_SYS
#define PIOS_INCLUDE_DELAY
#define PIOS_INCLUDE_LED
#define PIOS_INCLUDE_SDCARD
#define PIOS_INCLUDE_FREERTOS
#define PIOS_INCLUDE_COM
#define PIOS_INCLUDE_UDP

View File

@ -46,13 +46,6 @@
#define UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT 6
#define UAVOBJ_UPDATE_MODE_MASK 0x3
// FIXME: All this typedef for SDCARD needs to be abstracted away
#if !defined(PIOS_INCLUDE_SDCARD)
typedef struct {} FILEINFO;
#endif
typedef void* UAVObjHandle;
/**
@ -164,8 +157,10 @@ int32_t UAVObjPack(UAVObjHandle obj_handle, uint16_t instId, uint8_t* dataOut);
int32_t UAVObjSave(UAVObjHandle obj_handle, uint16_t instId);
int32_t UAVObjLoad(UAVObjHandle obj_handle, uint16_t instId);
int32_t UAVObjDelete(UAVObjHandle obj_handle, uint16_t instId);
#if defined(PIOS_INCLUDE_SDCARD)
int32_t UAVObjSaveToFile(UAVObjHandle obj_handle, uint16_t instId, FILEINFO* file);
UAVObjHandle UAVObjLoadFromFile(FILEINFO* file);
#endif
int32_t UAVObjSaveSettings();
int32_t UAVObjLoadSettings();
int32_t UAVObjDeleteSettings();

View File

@ -668,6 +668,7 @@ unlock_exit:
return rc;
}
#if defined(PIOS_INCLUDE_SDCARD)
/**
* Save the data of the specified object instance to the file system (SD card).
* The object will be appended and the file will not be closed.
@ -682,7 +683,6 @@ int32_t UAVObjSaveToFile(UAVObjHandle obj_handle, uint16_t instId,
{
PIOS_Assert(obj_handle);
#if defined(PIOS_INCLUDE_SDCARD)
uint32_t bytesWritten;
// Check for file system availability
if (PIOS_SDCARD_IsMounted() == 0) {
@ -741,9 +741,9 @@ int32_t UAVObjSaveToFile(UAVObjHandle obj_handle, uint16_t instId,
}
// Done
xSemaphoreGiveRecursive(mutex);
#endif /* PIOS_INCLUDE_SDCARD */
return 0;
}
#endif /* PIOS_INCLUDE_SDCARD */
/**
* Save the data of the specified object to the file system (SD card).
@ -811,6 +811,7 @@ int32_t UAVObjSave(UAVObjHandle obj_handle, uint16_t instId)
return 0;
}
#if defined(PIOS_INCLUDE_SDCARD)
/**
* Load an object from the file system (SD card).
* @param[in] file File to read from
@ -818,7 +819,6 @@ int32_t UAVObjSave(UAVObjHandle obj_handle, uint16_t instId)
*/
UAVObjHandle UAVObjLoadFromFile(FILEINFO * file)
{
#if defined(PIOS_INCLUDE_SDCARD)
uint32_t bytesRead;
struct UAVOBase *objEntry;
InstanceHandle instEntry;
@ -898,10 +898,8 @@ UAVObjHandle UAVObjLoadFromFile(FILEINFO * file)
// Unlock
xSemaphoreGiveRecursive(mutex);
return obj_handle;
#else /* PIOS_INCLUDE_SDCARD */
return NULL;
#endif
}
#endif /* PIOS_INCLUDE_SDCARD */
/**
* Load an object from the file system (SD card).

View File

@ -9,9 +9,7 @@ equals(copydata, 1) {
win32:CONFIG(release, debug|release) {
# copy Qt DLLs and phonon4
QT_DLLS = libgcc_s_dw2-1.dll \
mingwm10.dll \
phonon4.dll \
QT_DLLS = phonon4.dll \
QtCore4.dll \
QtGui4.dll \
QtNetwork4.dll \
@ -27,6 +25,13 @@ equals(copydata, 1) {
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_BINS]/$$dll\") $$targetPath(\"$$GCS_APP_PATH/$$dll\") $$addNewline()
}
# copy MinGW DLLs
MINGW_DLLS = libgcc_s_dw2-1.dll \
mingwm10.dll
for(dll, MINGW_DLLS) {
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_BINS]/../../../../../mingw/bin/$$dll\") $$targetPath(\"$$GCS_APP_PATH/$$dll\") $$addNewline()
}
# copy iconengines
QT_ICONENGINE_DLLS = qsvgicon4.dll
data_copy.commands += -@$(MKDIR) $$targetPath(\"$$GCS_APP_PATH/iconengines\") $$addNewline()

View File

@ -1385,26 +1385,6 @@
id="Telemetry-Critical"
style="fill:#cf0e0e;fill-opacity:1;stroke:#ffffff;stroke-width:0.29055119;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
</g>
<g
style="display:inline"
inkscape:label="SDCard-OK"
id="layer1"
inkscape:groupmode="layer" />
<g
style="display:inline"
inkscape:label="SDCard-Warning"
id="layer6"
inkscape:groupmode="layer" />
<g
style="display:inline"
inkscape:label="SDCard-Error"
id="layer11"
inkscape:groupmode="layer" />
<g
style="display:inline"
inkscape:label="SDCard-Critical"
id="layer20"
inkscape:groupmode="layer" />
<g
style="display:none"
inkscape:label="Memory-OK"

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 235 KiB

View File

@ -158,7 +158,7 @@ namespace Utils {
{
double Lat = LLA[0];
double Lon = LLA[1];
double AltEllipsoid = LLA[2];
double AltEllipsoid = LLA[2]/1000.0; // convert to km
// ***********
// range check supplied params

View File

@ -180,7 +180,6 @@ void VehicleConfig::setMixerType(UAVDataObject* mixer, int channel, MixerTypeEle
if (mixerType >= 0 && mixerType < mixerTypeDescriptions.count())
{
field->setValue(mixerTypeDescriptions[mixerType]);
mixer->updated();
}
}
}
@ -228,7 +227,6 @@ void VehicleConfig::setMixerVectorValue(UAVDataObject* mixer, int channel, Mixer
if (field) {
field->setDouble(value, elementName);
mixer->updated();
}
}
}

View File

@ -82,12 +82,12 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent)
connect(m_config->wzBack,SIGNAL(clicked()),this,SLOT(wzBack()));
m_config->stackedWidget->setCurrentIndex(0);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos1,0);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos2,1);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos3,2);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos4,3);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos5,4);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos6,5);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos1,0,1,true);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos2,1,1,true);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos3,2,1,true);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos4,3,1,true);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos5,4,1,true);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos6,5,1,true);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModeNumber",m_config->fmsPosNum);
addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization1Settings",m_config->fmsSsPos1Roll,"Roll");

View File

@ -135,6 +135,14 @@ void ConfigStabilizationWidget::processLinkedWidgets(QWidget * widget)
{
m_stabilization->RateRollILimit_2->setValue(m_stabilization->RatePitchILimit->value());
}
else if(widget== m_stabilization->RollRateKd)
{
m_stabilization->PitchRateKd->setValue(m_stabilization->RollRateKd->value());
}
else if(widget== m_stabilization->PitchRateKd)
{
m_stabilization->RollRateKd->setValue(m_stabilization->PitchRateKd->value());
}
}
if(m_stabilization->checkBox_8->checkState()==Qt::Checked)
{

View File

@ -1,3 +1,30 @@
/**
******************************************************************************
*
* @file aerosimrc.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* 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 "aerosimrc.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>

View File

@ -1,3 +1,30 @@
/**
******************************************************************************
*
* @file aerosimrc.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* 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 AEROSIMRC_H
#define AEROSIMRC_H

View File

@ -0,0 +1,10 @@
TEMPLATE = subdirs
win32 {
SUBDIRS += plugin
}
SUBDIRS += udptest
plugin.file = src/plugin.pro
udptest.file = src/udptest.pro

View File

@ -0,0 +1,206 @@
/**
******************************************************************************
*
* @file aerosimrcdatastruct.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy 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 AEROSIMRCDATASTRUCT_H
#define AEROSIMRCDATASTRUCT_H
#include <QtCore>
const quint8 AEROSIMRC_MAX_CHANNELS = 39;
const quint16 DBG_BUFFER_MAX_SIZE = 4096;
#define MAX_DLL_USER_MENU_ITEMS 16
#define OBSOLETE_MIT_COMMAND (1 << 0)
#define OBSOLETE_MIT_CHECKBOX (1 << 1)
#define OBSOLETE_MIT_SEPARATOR (1 << 7)
#define PACK_STRUCT __attribute__((packed))
struct simToPlugin
{
quint16 structSize;
float simTimeStep;
float chSimTX[AEROSIMRC_MAX_CHANNELS];
float chSimRX[AEROSIMRC_MAX_CHANNELS];
uchar *OSDVideoBuf;
quint32 simMenuStatus;
float initPosX;
float initPosY;
float initPosZ;
float initHeading;
float initPitch;
float initRoll;
float wpHomeX;
float wpHomeY;
float wpHomeLat;
float wpHomeLong;
const char *wpHomeDesc; // (m, deg, string)
float wpAX;
float wpAY;
float wpALat;
float wpALong;
const char *wpADesc; // (m, deg, string)
float wpBX;
float wpBY;
float wpBLat;
float wpBLong;
const char *wpBDesc; // (m, deg, string)
float wpCX;
float wpCY;
float wpCLat;
float wpCLong;
const char *wpCDesc; // (m, deg, string)
float wpDX;
float wpDY;
float wpDLat;
float wpDLong;
const char *wpDDesc; // (m, deg, string)
float posX;
float posY;
float posZ;
float velX;
float velY;
float velZ;
float angVelX;
float angVelY;
float angVelZ;
float accelX;
float accelY;
float accelZ;
qreal latitude;
qreal longitude;
float AGL;
float heading;
float pitch;
float roll;
float windVelX;
float windVelY;
float windVelZ;
float eng1RPM;
float eng2RPM;
float eng3RPM;
float eng4RPM;
float voltage; // V
float current; // A
float consumedCharge; // Ah
float capacity; // Ah
float fuelConsumed; // l
float fuelTankCapacity; // l
// ver 3.83
qint16 screenW;
qint16 screenH;
// Model Orientation Matrix (X=Right, Y=Front, Z=Up)
float axisXx;
float axisXy;
float axisXz;
float axisYx;
float axisYy;
float axisYz;
float axisZx;
float axisZy;
float axisZz;
// Model data in body frame coordinates (X=Right, Y=Front, Z=Up)
float velXm; // m/s Model velocity in body coordinates
float velYm;
float velZm;
float angVelXm; // rad/s Model angular velocity in body coordinates
float angVelYm;
float angVelZm;
float accelXm; // m/s/s Model acceleration in body coordinates
float accelYm;
float accelZm;
// ver 3.90
quint32 OSDVideoBufSize;
} PACK_STRUCT ; // normal - 592, packed - 582 OK (3.81)
// normal - ???, packed - 658 OK (3.83)
// normal - ???, packed - 662 OK (3.90)
struct pluginToSim
{
quint16 structSize;
const char *dbgInfoText;
uchar chOverTX[AEROSIMRC_MAX_CHANNELS];
float chNewTX[AEROSIMRC_MAX_CHANNELS];
uchar chOverRX[AEROSIMRC_MAX_CHANNELS];
float chNewRX[AEROSIMRC_MAX_CHANNELS];
float newPosX; // m
float newPosY;
float newPosZ;
float newVelX; // m/s
float newVelY;
float newVelZ;
float newAngVelX; // rad/s
float newAngVelY;
float newAngVelZ;
float newHeading; // rad
float newPitch;
float newRoll;
quint32 modelOverrideFlags;
quint32 newMenuStatus;
quint8 isOSDShow;
quint8 isOSDChanged;
quint16 OSDWindow_DX;
quint16 OSDWindow_DY;
float OSDScale;
float newWindVelX;
float newWindVelY;
float newWindVelZ;
float newEng1RPM;
float newEng2RPM;
float newEng3RPM;
float newEng4RPM;
float newVoltage;
float newCurrent;
float newConsumedCharge;
float newFuelConsumed;
quint8 modelCrashInhibit;
// ver 3.83
qint16 newScreenW; // Simulator window position and size on screen
qint16 newScreenH;
qint16 newScreenX;
qint16 newScreenY;
} PACK_STRUCT ; // normal 516, packed 507 OK (3.81)
// normal ???, packed 515 OK (3.83 & 3.90)
struct TPluginMenuItem
{
quint32 OBSOLETE_eType;
char *OBSOLETE_strName;
} PACK_STRUCT ;
struct pluginInit
{
quint32 nStructSize;
char *OBSOLETE_strMenuTitle;
TPluginMenuItem OBSOLETE_atMenuItem[MAX_DLL_USER_MENU_ITEMS];
const char *strPluginFolder;
const char *strOutputFolder;
} PACK_STRUCT ; // normal - 144, packed - 144 OK (3.81 & 3.83 & 3.90)
#undef PACK_STRUCT
#endif // AEROSIMRCDATASTRUCT_H

View File

@ -0,0 +1,102 @@
/**
******************************************************************************
*
* @file enums.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy 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 ENUMS_H
#define ENUMS_H
// Custom Menu Item masks
enum MenuMasks {
MenuEnable = (1 << 0),
MenuTx = (1 << 1),
MenuRx = (1 << 2),
MenuScreen = (1 << 3),
MenuNextWpt = (1 << 4),
MenuCmdReset = (1 << 5),
MenuLedBlue = (1 << 6),
MenuLedGreen = (1 << 7),
MenuFMode1 = (1 << 8),
MenuFMode2 = (1 << 9),
MenuFMode3 = (1 << 10)
};
enum EOverrideFlags
{
OVR_POS = (1 << 0),
OVR_VEL = (1 << 1),
OVR_ANG_VEL = (1 << 2),
OVR_HPR = (1 << 3), // Override Heading, Pitch and Roll
OVR_WIND_VEL = (1 << 4), // Override Wind velocity at model
OVR_ENGINE_RPM = (1 << 5), // Override RPM of all Engines or Motors
OVR_BAT_VOLT = (1 << 6), // Override motor Battery Voltage
OVR_BAT_AMP = (1 << 7), // Override motor Battery current
OVR_BAT_AH_CONSUMED = (1 << 8), // Override motor Battery AmpsHour consumed
OVR_FUEL_CONSUMED = (1 << 9) // Override Fuel consumed (gas & jet engines)
};
enum Channels {
Ch1Aileron,
Ch2Elevator,
Ch3Throttle,
Ch4Rudder,
Ch5,
Ch6,
Ch7,
Ch8,
Ch9,
Ch10Retracts,
Ch11Flaps,
Ch12FPVCamPan,
Ch13FPVCamTilt,
Ch14Brakes,
Ch15Spoilers,
Ch16Smoke,
Ch17Fire,
Ch18FlightMode,
Ch19ALTHold,
Ch20FPVTiltHold,
Ch21ResetModel,
Ch22MouseTX,
Ch23Plugin1,
Ch24Plugin2,
Ch25ThrottleHold,
Ch26CareFree,
Ch27FPVCamRoll,
Ch28LMotorDual,
Ch29RMotorDual,
Ch30Mix,
Ch31Mix,
Ch32Mix,
Ch33Mix,
Ch34Mix,
Ch35Mix,
Ch36Mix,
Ch37Mix,
Ch38Mix,
Ch39Mix
};
#endif // ENUMS_H

View File

@ -0,0 +1,394 @@
/**
******************************************************************************
*
* @file plugin.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy 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 "plugin.h"
#include "udpconnect.h"
#include "qdebughandler.h"
#include "enums.h"
#include "settings.h"
bool isFirstRun = true;
QString debugInfo(DBG_BUFFER_MAX_SIZE, ' ');
QString pluginFolder(MAX_PATH, ' ');
QString outputFolder(MAX_PATH, ' ');
QList<quint16> videoModes;
QTime ledTimer;
UdpSender *sndr;
UdpReceiver *rcvr;
const float RAD2DEG = (float)(180.0 / M_PI);
const float DEG2RAD = (float)(M_PI / 180.0);
//extern "C" int __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
extern "C" int __stdcall DllMain(void*, quint32 fdwReason, void*)
{
switch (fdwReason) {
case 0:
// qDebug() << hinstDLL << "DLL_PROCESS_DETACH " << lpvReserved;
// free resources here
rcvr->stop();
rcvr->wait(500);
delete rcvr;
delete sndr;
qDebug("------");
break;
case 1:
// qDebug() << hinstDLL << " DLL_PROCESS_ATTACH " << lpvReserved;
break;
case 2:
// qDebug() << hinstDLL << "DLL_THREAD_ATTACH " << lpvReserved;
break;
case 3:
// qDebug() << hinstDLL << "DLL_THREAD_DETACH " << lpvReserved;
break;
}
return true;
}
SIM_DLL_EXPORT void AeroSIMRC_Plugin_ReportStructSizes(quint32 *sizeSimToPlugin,
quint32 *sizePluginToSim,
quint32 *sizePluginInit)
{
// debug redirection
qInstallMsgHandler(myQDebugHandler);
qDebug() << "AeroSIMRC_Plugin_ReportStructSizes";
*sizeSimToPlugin = sizeof(simToPlugin);
*sizePluginToSim = sizeof(pluginToSim);
*sizePluginInit = sizeof(pluginInit);
qDebug() << "sizeSimToPlugin = " << *sizeSimToPlugin;
qDebug() << "sizePluginToSim = " << *sizePluginToSim;
qDebug() << "sizePluginInit = " << *sizePluginInit;
}
SIM_DLL_EXPORT void AeroSIMRC_Plugin_Init(pluginInit *p)
{
qDebug() << "AeroSIMRC_Plugin_Init begin";
pluginFolder = p->strPluginFolder;
outputFolder = p->strOutputFolder;
ledTimer.restart();
Settings *ini = new Settings(pluginFolder);
ini->read();
videoModes = ini->getVideoModes();
sndr = new UdpSender(ini->getOutputMap(), ini->isFromTX());
sndr->init(ini->remoteHost(), ini->remotePort());
rcvr = new UdpReceiver(ini->getInputMap(), ini->isToRX());
rcvr->init(ini->localHost(), ini->localPort());
// run thread
rcvr->start();
delete ini;
qDebug() << "AeroSIMRC_Plugin_Init done";
}
//-----------------------------------------------------------------------------
void Run_Command_Reset(/*const simToPlugin *stp,
pluginToSim *pts*/)
{
// Print some debug info, although it will only be seen during one frame
debugInfo.append("\nRESET");
}
void Run_Command_WindowSizeAndPos(const simToPlugin *stp,
pluginToSim *pts)
{
static quint8 snSequence = 0;
quint8 idx = snSequence * 4;
if (snSequence >= videoModes.at(0)) { // set fullscreen
pts->newScreenX = 0;
pts->newScreenY = 0;
pts->newScreenW = stp->screenW;
pts->newScreenH = stp->screenH;
snSequence = 0;
} else { // set video mode from config
pts->newScreenX = videoModes.at(idx + 1);
pts->newScreenY = videoModes.at(idx + 2);
pts->newScreenW = videoModes.at(idx + 3);
pts->newScreenH = videoModes.at(idx + 4);
snSequence++;
}
}
void Run_Command_MoveToNextWaypoint(const simToPlugin *stp,
pluginToSim *pts)
{
static quint8 snSequence = 0;
switch(snSequence) {
case 0:
pts->newPosX = stp->wpAX;
pts->newPosY = stp->wpAY;
pts->newPosZ = 100.0;
break;
case 1:
pts->newPosX = stp->wpBX;
pts->newPosY = stp->wpBY;
pts->newPosZ = 100.0;
break;
case 2:
pts->newPosX = stp->wpCX;
pts->newPosY = stp->wpCY;
pts->newPosZ = 100.0;
break;
case 3:
pts->newPosX = stp->wpDX;
pts->newPosY = stp->wpDY;
pts->newPosZ = 100.0;
break;
case 4:
pts->newPosX = stp->wpHomeX;
pts->newPosY = stp->wpHomeY;
pts->newPosZ = 100.0;
break;
default:
qFatal("Run_Command_MoveToNextWaypoint switch error");
}
pts->modelOverrideFlags = 0;
pts->modelOverrideFlags |= OVR_POS;
snSequence++;
if(snSequence > 4)
snSequence = 0;
}
void Run_BlinkLEDs(const simToPlugin *stp,
pluginToSim *pts)
{
if ((stp->simMenuStatus & MenuEnable) != 0) {
pts->newMenuStatus |= MenuLedGreen;
int timeout;
quint8 armed;
quint8 mode;
rcvr->getFlighStatus(armed, mode);
debugInfo.append(QString("armed: %1, mode: %2\n").arg(armed).arg(mode));
if (armed == 0) // disarm
timeout = 1000;
else if (armed == 1) // arming
timeout = 40;
else if (armed == 2) // armed
timeout = 100;
else // unknown
timeout = 2000;
if (ledTimer.elapsed() > timeout) {
ledTimer.restart();
pts->newMenuStatus ^= MenuLedBlue;
}
if (mode == 6) {
pts->newMenuStatus |= MenuFMode3;
pts->newMenuStatus |= MenuFMode2;
pts->newMenuStatus |= MenuFMode1;
} else if (mode == 5) {
pts->newMenuStatus |= MenuFMode3;
pts->newMenuStatus |= MenuFMode2;
pts->newMenuStatus &= ~MenuFMode1;
} else if (mode == 4) {
pts->newMenuStatus |= MenuFMode3;
pts->newMenuStatus &= ~MenuFMode2;
pts->newMenuStatus |= MenuFMode1;
} else if (mode == 3) {
pts->newMenuStatus |= MenuFMode3;
pts->newMenuStatus &= ~MenuFMode2;
pts->newMenuStatus &= ~MenuFMode1;
} else if (mode == 2) {
pts->newMenuStatus &= ~MenuFMode3;
pts->newMenuStatus |= MenuFMode2;
pts->newMenuStatus &= ~MenuFMode1;
} else if (mode == 1) {
pts->newMenuStatus &= ~MenuFMode3;
pts->newMenuStatus &= ~MenuFMode2;
pts->newMenuStatus |= MenuFMode1;
} else /*(mode == 0)*/ {
pts->newMenuStatus &= ~MenuFMode3;
pts->newMenuStatus &= ~MenuFMode2;
pts->newMenuStatus &= ~MenuFMode1;
}
} else {
pts->newMenuStatus = 0;
}
}
void InfoText(const simToPlugin *stp,
pluginToSim *pts)
{
debugInfo.append(
QString(
"Plugin Folder = %1\n"
"Output Folder = %2\n"
"nStructSize = %3 "
"fIntegrationTimeStep = %4\n"
"\n"
"Aileron TX = %5 RX = %6 RCMD TX = %7 RX = %8\n"
"Elevator TX = %9 RX = %10 RCMD TX = %11 RX = %12\n"
"Throttle TX = %13 RX = %14 RCMD TX = %15 RX = %16\n"
"Rudder TX = %17 RX = %18 RCMD TX = %19 RX = %20\n"
"Channel5 TX = %21 RX = %22 RCMD TX = %23 RX = %24\n"
"Channel6 TX = %25 RX = %26 RCMD TX = %27 RX = %28\n"
"Channel7 TX = %29 RX = %30 RCMD TX = %31 RX = %32\n"
"PluginCh1 TX = %33 RX = %34 RCMD TX = %35 RX = %36\n"
"PluginCh2 TX = %37 RX = %38 RCMD TX = %39 RX = %40\n"
"FPVCamPan TX = %41 RX = %42 RCMD TX = %43 RX = %44\n"
"FPVCamTil TX = %45 RX = %46 RCMD TX = %47 RX = %48\n"
"\n"
"MenuItems = %49\n"
// Model data
"\n"
"fPosX,Y,Z = (%50, %51, %52)\n"
"fVelX,Y,Z = (%53, %54, %55)\n"
"fAngVelX,Y,Z = (%56, %57, %58)\n"
"fAccelX,Y,Z = (%59, %60, %61)\n"
"\n"
"Lat, Long = %62, %63\n"
"fHeightAboveTerrain = %64\n"
"\n"
"fHeading = %65 fPitch = %66 fRoll = %67\n"
)
.arg(pluginFolder)
.arg(outputFolder)
.arg(stp->structSize)
.arg(1.0 / stp->simTimeStep, 4, 'f', 1)
.arg(stp->chSimTX[Ch1Aileron], 5, 'f', 2)
.arg(stp->chSimRX[Ch1Aileron], 5, 'f', 2)
.arg(pts->chNewTX[Ch1Aileron], 5, 'f', 2)
.arg(pts->chNewRX[Ch1Aileron], 5, 'f', 2)
.arg(stp->chSimTX[Ch2Elevator], 5, 'f', 2)
.arg(stp->chSimRX[Ch2Elevator], 5, 'f', 2)
.arg(pts->chNewTX[Ch2Elevator], 5, 'f', 2)
.arg(pts->chNewRX[Ch2Elevator], 5, 'f', 2)
.arg(stp->chSimTX[Ch3Throttle], 5, 'f', 2)
.arg(stp->chSimRX[Ch3Throttle], 5, 'f', 2)
.arg(pts->chNewTX[Ch3Throttle], 5, 'f', 2)
.arg(pts->chNewRX[Ch3Throttle], 5, 'f', 2)
.arg(stp->chSimTX[Ch4Rudder], 5, 'f', 2)
.arg(stp->chSimRX[Ch4Rudder], 5, 'f', 2)
.arg(pts->chNewTX[Ch4Rudder], 5, 'f', 2)
.arg(pts->chNewRX[Ch4Rudder], 5, 'f', 2)
.arg(stp->chSimTX[Ch5], 5, 'f', 2)
.arg(stp->chSimRX[Ch5], 5, 'f', 2)
.arg(pts->chNewTX[Ch5], 5, 'f', 2)
.arg(pts->chNewRX[Ch5], 5, 'f', 2)
.arg(stp->chSimTX[Ch6], 5, 'f', 2)
.arg(stp->chSimRX[Ch6], 5, 'f', 2)
.arg(pts->chNewTX[Ch6], 5, 'f', 2)
.arg(pts->chNewRX[Ch6], 5, 'f', 2)
.arg(stp->chSimTX[Ch7], 5, 'f', 2)
.arg(stp->chSimRX[Ch7], 5, 'f', 2)
.arg(pts->chNewTX[Ch7], 5, 'f', 2)
.arg(pts->chNewRX[Ch7], 5, 'f', 2)
.arg(stp->chSimTX[Ch23Plugin1], 5, 'f', 2)
.arg(stp->chSimRX[Ch23Plugin1], 5, 'f', 2)
.arg(pts->chNewTX[Ch23Plugin1], 5, 'f', 2)
.arg(pts->chNewRX[Ch23Plugin1], 5, 'f', 2)
.arg(stp->chSimTX[Ch24Plugin2], 5, 'f', 2)
.arg(stp->chSimRX[Ch24Plugin2], 5, 'f', 2)
.arg(pts->chNewTX[Ch24Plugin2], 5, 'f', 2)
.arg(pts->chNewRX[Ch24Plugin2], 5, 'f', 2)
.arg(stp->chSimTX[Ch12FPVCamPan], 5, 'f', 2)
.arg(stp->chSimRX[Ch12FPVCamPan], 5, 'f', 2)
.arg(pts->chNewTX[Ch12FPVCamPan], 5, 'f', 2)
.arg(pts->chNewRX[Ch12FPVCamPan], 5, 'f', 2)
.arg(stp->chSimTX[Ch13FPVCamTilt], 5, 'f', 2)
.arg(stp->chSimRX[Ch13FPVCamTilt], 5, 'f', 2)
.arg(pts->chNewTX[Ch13FPVCamTilt], 5, 'f', 2)
.arg(pts->chNewRX[Ch13FPVCamTilt], 5, 'f', 2)
.arg(stp->simMenuStatus)
.arg(stp->posX, 5, 'f', 2)
.arg(stp->posY, 5, 'f', 2)
.arg(stp->posZ, 5, 'f', 2)
.arg(stp->velX, 5, 'f', 2)
.arg(stp->velY, 5, 'f', 2)
.arg(stp->velZ, 5, 'f', 2)
.arg(stp->angVelXm, 5, 'f', 2)
.arg(stp->angVelYm, 5, 'f', 2)
.arg(stp->angVelZm, 5, 'f', 2)
.arg(stp->accelXm, 5, 'f', 2)
.arg(stp->accelYm, 5, 'f', 2)
.arg(stp->accelZm, 5, 'f', 2)
.arg(stp->latitude, 5, 'f', 2)
.arg(stp->longitude, 5, 'f', 2)
.arg(stp->AGL, 5, 'f', 2)
.arg(stp->heading*RAD2DEG, 5, 'f', 2)
.arg(stp->pitch*RAD2DEG, 5, 'f', 2)
.arg(stp->roll*RAD2DEG, 5, 'f', 2)
);
}
SIM_DLL_EXPORT void AeroSIMRC_Plugin_Run(const simToPlugin *stp,
pluginToSim *pts)
{
debugInfo = "---\n";
// By default do not change the Menu Items of type CheckBox
pts->newMenuStatus = stp->simMenuStatus;
// Extract Menu Commands from Flags
bool isReset = (stp->simMenuStatus & MenuCmdReset) != 0;
bool isEnable = (stp->simMenuStatus & MenuEnable) != 0;
bool isTxON = (stp->simMenuStatus & MenuTx) != 0;
bool isRxON = (stp->simMenuStatus & MenuRx) != 0;
bool isScreen = (stp->simMenuStatus & MenuScreen) != 0;
bool isNextWp = (stp->simMenuStatus & MenuNextWpt) != 0;
// Run commands
if (isReset) {
Run_Command_Reset(/*stp, pts*/);
} else if (isScreen) {
Run_Command_WindowSizeAndPos(stp, pts);
} else if (isNextWp) {
Run_Command_MoveToNextWaypoint(stp, pts);
} else {
Run_BlinkLEDs(stp, pts);
if (isEnable) {
if (isTxON)
sndr->sendDatagram(stp);
if (isRxON)
rcvr->setChannels(pts);
}
// network lag
debugInfo.append(QString("out: %1, inp: %2, delta: %3\n")
.arg(sndr->pcks() - 1)
.arg(rcvr->pcks())
.arg(sndr->pcks() - rcvr->pcks() - 1)
);
}
// debug info is shown on the screen
InfoText(stp, pts);
pts->dbgInfoText = debugInfo.toAscii();
isFirstRun = false;
}

View File

@ -0,0 +1,53 @@
/**
******************************************************************************
*
* @file plugin.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy 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 PLUGIN_H
#define PLUGIN_H
#include <QtCore>
#include <QTime>
#include <QList>
#include "aerosimrcdatastruct.h"
#define SIM_DLL_EXPORT extern "C" __declspec(dllexport)
SIM_DLL_EXPORT void AeroSIMRC_Plugin_ReportStructSizes(
quint32 *sizeSimToPlugin,
quint32 *sizePluginToSim,
quint32 *sizePluginInit
);
SIM_DLL_EXPORT void AeroSIMRC_Plugin_Init(
pluginInit *p
);
SIM_DLL_EXPORT void AeroSIMRC_Plugin_Run(
const simToPlugin *stp,
pluginToSim *pts
);
#endif // PLUGIN_H

View File

@ -0,0 +1,71 @@
!win32 {
error("AeroSimRC plugin is only available for win32 platform")
}
include(../../../../../openpilotgcs.pri)
QT += network
QT -= gui
TEMPLATE = lib
TARGET = plugin_AeroSIMRC
RES_DIR = $${PWD}/resources
SIM_DIR = $$GCS_BUILD_TREE/../AeroSIM-RC
PLUGIN_DIR = $$SIM_DIR/Plugin/CopterControl
DLLDESTDIR = $$PLUGIN_DIR
HEADERS = \
aerosimrcdatastruct.h \
enums.h \
plugin.h \
qdebughandler.h \
udpconnect.h \
settings.h
SOURCES = \
qdebughandler.cpp \
plugin.cpp \
udpconnect.cpp \
settings.cpp
# Resemble the AeroSimRC directory structure and copy plugin files and resources
equals(copydata, 1) {
# Windows release only
win32:CONFIG(release, debug|release) {
data_copy.commands += -@$(MKDIR) $$targetPath(\"$$PLUGIN_DIR\") $$addNewline()
# resources and sample configuration
PLUGIN_RESOURCES = \
cc_off.tga \
cc_off_hover.tga \
cc_on.tga \
cc_on_hover.tga \
cc_plugin.ini \
plugin.txt
for(res, PLUGIN_RESOURCES) {
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$RES_DIR/$$res\") $$targetPath(\"$$PLUGIN_DIR/$$res\") $$addNewline()
}
# Qt DLLs
QT_DLLS = \
QtCore4.dll \
QtNetwork4.dll
for(dll, QT_DLLS) {
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_BINS]/$$dll\") $$targetPath(\"$$SIM_DIR/$$dll\") $$addNewline()
}
# MinGW DLLs
MINGW_DLLS = \
libgcc_s_dw2-1.dll \
mingwm10.dll
for(dll, MINGW_DLLS) {
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_BINS]/../../../../../mingw/bin/$$dll\") $$targetPath(\"$$SIM_DIR/$$dll\") $$addNewline()
}
data_copy.target = FORCE
QMAKE_EXTRA_TARGETS += data_copy
}
}

View File

@ -0,0 +1,64 @@
/**
******************************************************************************
*
* @file qdebughandler.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy 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 "qdebughandler.h"
void myQDebugHandler(QtMsgType type, const char *msg)
{
static bool firstRun = true;
QString txt;
switch (type) {
case QtDebugMsg:
txt = QString("Debug: %1").arg(msg);
break;
case QtWarningMsg:
txt = QString("Warning: %1").arg(msg);
break;
case QtCriticalMsg:
txt = QString("Critical: %1").arg(msg);
break;
case QtFatalMsg:
txt = QString("Fatal: %1").arg(msg);
break;
}
QFile outFile("dbglog.txt");
outFile.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream ts(&outFile);
QTime time;
if (firstRun) {
ts << endl << endl;
firstRun = false;
}
ts << time.currentTime().toString("hh:mm:ss.zzz") << " " << txt << endl;
if (type == QtFatalMsg)
abort();
}

View File

@ -0,0 +1,37 @@
/**
******************************************************************************
*
* @file qdebughandler.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy 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 QDEBUGHANDLER_H
#define QDEBUGHANDLER_H
#include <QDebug>
#include <QFile>
#include <QTime>
void myQDebugHandler(QtMsgType type, const char *msg);
#endif // QDEBUGHANDLER_H

View File

@ -0,0 +1,55 @@
[General]
; Network settings
listen_on_host = 127.0.0.1
listen_on_port = 40200
send_to_host = 127.0.0.1
send_to_port = 40100
; Channels enumerator, applicable for the AeroSIM RC version 3.90+
all_channels = Ch1-Aileron Ch2-Elevator Ch3-Throttle Ch4-Rudder Ch5 Ch6 Ch7 Ch8 Ch9 Ch10-Retracts Ch11-Flaps Ch12-FPV-Pan Ch13-FPV-Tilt Ch14-Brakes Ch15-Spoilers Ch16-Smoke Ch17-Fire Ch18-Flight-Mode Ch19-ALT-Hold Ch20-FPV-Tilt-Hold Ch21-Reset-Model Ch22-MouseTX Ch23-Plugin-1 Ch24-Plugin-2 Ch25-Throttle-Hold Ch26-CareFree Ch27-FPV-Roll Ch28-L-Motor-Dual Ch29-R-Motor-Dual Ch30-Mix Ch31-Mix Ch32-Mix Ch33-Mix Ch34-Mix Ch35-Mix Ch36-Mix Ch37-Mix Ch38-Mix Ch39-Mix
[Input]
; Map CopterControl channels to simulator channels
; To use internal simulator channels just comment the mapping here
cc_channel_1 = Ch1-Aileron
cc_channel_2 = Ch2-Elevator
cc_channel_3 = Ch3-Throttle
cc_channel_4 = Ch4-Rudder
;cc_channel_5 = Ch27-FPV-Roll
cc_channel_6 = Ch13-FPV-Tilt
;cc_channel_7 = Ch12-FPV-Pan
;cc_channel_8 =
;cc_channel_9 =
;cc_channel_10=
; Control TX or RX (before or after mixes)
send_to = RX
[Output]
; Map simulator channels to GCS HiTL/CopterControl channels
; Only mapped channels will be sent to the GCS
sim_channel_1 = Ch1-Aileron
sim_channel_2 = Ch2-Elevator
sim_channel_3 = Ch3-Throttle
sim_channel_4 = Ch4-Rudder
sim_channel_5 = Ch23-Plugin-1
;sim_channel_6 = Ch27-FPV-Roll
sim_channel_7 = Ch13-FPV-Tilt
;sim_channel_8 = Ch12-FPV-Pan
; take values from TX or RX (before or after mixes)
take_from = TX
[Video]
; Windowed simulator mode configurations
; Each resolution defines the upper left corner and width/hight.
; User can cycle through all resolutions using the menu command.
number_of_resolutions = 2
; x, y, width, height
resolution_1 = 50 50 640 720
resolution_2 = 0 0 800 480

View File

@ -0,0 +1,86 @@
.NAME "CopterControl"
.HELP_EN "\
OpenPilot CopterControl HiTL plugin for AeroSIM RC"
.IMAGE_OFF "cc_off.tga"
.IMAGE_ON "cc_on.tga"
.IMAGE_OFF_MOUSE_HOVER "cc_off_hover.tga"
.IMAGE_ON_MOUSE_HOVER "cc_on_hover.tga"
.MENU_ITEM_00_NAME "Enable"
.MENU_ITEM_00_TYPE CHECKBOX
.MENU_ITEM_00_HAS_SEPARATOR 0
.MENU_ITEM_00_MOUSE_RECT_XY 89 91
.MENU_ITEM_00_MOUSE_RECT_DXDY 48 48
.MENU_ITEM_00_HIDE_MENU_ITEM 0
.MENU_ITEM_01_NAME "Transmit data"
.MENU_ITEM_01_TYPE CHECKBOX
.MENU_ITEM_01_HAS_SEPARATOR 0
.MENU_ITEM_01_MOUSE_RECT_XY 110 166
.MENU_ITEM_01_MOUSE_RECT_DXDY 52 34
.MENU_ITEM_01_HIDE_MENU_ITEM 0
.MENU_ITEM_02_NAME "Receive data"
.MENU_ITEM_02_TYPE CHECKBOX
.MENU_ITEM_02_HAS_SEPARATOR 1
.MENU_ITEM_02_MOUSE_RECT_XY 36 166
.MENU_ITEM_02_MOUSE_RECT_DXDY 52 34
.MENU_ITEM_02_HIDE_MENU_ITEM 0
.MENU_ITEM_03_NAME "Change window size and position"
.MENU_ITEM_03_TYPE COMMAND
.MENU_ITEM_03_HAS_SEPARATOR 0
.MENU_ITEM_03_MOUSE_RECT_XY 0 0
.MENU_ITEM_03_MOUSE_RECT_DXDY 0 0
.MENU_ITEM_03_HIDE_MENU_ITEM 0
.MENU_ITEM_04_NAME "Move to next waypoint"
.MENU_ITEM_04_TYPE COMMAND
.MENU_ITEM_04_HAS_SEPARATOR 0
.MENU_ITEM_04_MOUSE_RECT_XY 0 0
.MENU_ITEM_04_MOUSE_RECT_DXDY 0 0
.MENU_ITEM_04_HIDE_MENU_ITEM 0
.MENU_ITEM_05_NAME "no action"
.MENU_ITEM_05_TYPE COMMAND
.MENU_ITEM_05_HAS_SEPARATOR 0
.MENU_ITEM_05_MOUSE_RECT_XY 0 0
.MENU_ITEM_05_MOUSE_RECT_DXDY 0 0
.MENU_ITEM_05_HIDE_MENU_ITEM 0
.MENU_ITEM_06_NAME "Blue LED"
.MENU_ITEM_06_TYPE CHECKBOX
.MENU_ITEM_06_HAS_SEPARATOR 0
.MENU_ITEM_06_MOUSE_RECT_XY 6 40
.MENU_ITEM_06_MOUSE_RECT_DXDY 15 12
.MENU_ITEM_06_HIDE_MENU_ITEM 1
.MENU_ITEM_07_NAME "Green LED"
.MENU_ITEM_07_TYPE CHECKBOX
.MENU_ITEM_07_HAS_SEPARATOR 0
.MENU_ITEM_07_MOUSE_RECT_XY 6 52
.MENU_ITEM_07_MOUSE_RECT_DXDY 15 12
.MENU_ITEM_07_HIDE_MENU_ITEM 1
.MENU_ITEM_08_NAME "FlightMode 1"
.MENU_ITEM_08_TYPE CHECKBOX
.MENU_ITEM_08_HAS_SEPARATOR 0
.MENU_ITEM_08_MOUSE_RECT_XY 40 19
.MENU_ITEM_08_MOUSE_RECT_DXDY 38 38
.MENU_ITEM_08_HIDE_MENU_ITEM 1
.MENU_ITEM_09_NAME "FlightMode 2"
.MENU_ITEM_09_TYPE CHECKBOX
.MENU_ITEM_09_HAS_SEPARATOR 0
.MENU_ITEM_09_MOUSE_RECT_XY 78 19
.MENU_ITEM_09_MOUSE_RECT_DXDY 38 38
.MENU_ITEM_09_HIDE_MENU_ITEM 1
.MENU_ITEM_10_NAME "FlightMode 3"
.MENU_ITEM_10_TYPE CHECKBOX
.MENU_ITEM_10_HAS_SEPARATOR 0
.MENU_ITEM_10_MOUSE_RECT_XY 115 19
.MENU_ITEM_10_MOUSE_RECT_DXDY 38 38
.MENU_ITEM_10_HIDE_MENU_ITEM 1

View File

@ -0,0 +1,98 @@
/**
******************************************************************************
*
* @file settings.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy 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 "settings.h"
Settings::Settings(QString settingsPath, QObject *parent) :
QObject(parent)
{
settings = new QSettings(settingsPath + "/cc_plugin.ini", QSettings::IniFormat);
// default settings
sendToHost = "127.0.0.1";
sendToPort = 40100;
listenOnHost = "127.0.0.1";
listenOnPort = 40200;
channels.reserve(60);
for (quint8 i = 0; i < 10; ++i)
inputMap << 255;
for (quint8 i = 0; i < 8; ++i)
outputMap << 255;
sendToRX = true;
takeFromTX = true;
videoModes << 1 << 50 << 50 << 800 << 600;
}
void Settings::read()
{
// network
listenOnHost = settings->value("listen_on_host", listenOnHost).toString();
listenOnPort = settings->value("listen_on_port", listenOnPort).toInt();
sendToHost = settings->value("send_to_host", sendToHost).toString();
sendToPort = settings->value("send_to_port", sendToPort).toInt();
QString allChannels = settings->value("all_channels").toString();
QString chan;
int i = 0;
foreach (chan, allChannels.split(" "))
channels.insert(chan, i++);
// inputs
QString num = "";
QString map = "";
for (quint8 i = 0; i < 10; ++i) {
num = QString::number(i+1);
map = settings->value("Input/cc_channel_" + num).toString();
inputMap[i] = channels.value(map, inputMap.at(i));
}
QString sendTo = settings->value("Input/send_to", "RX").toString();
sendToRX = (sendTo == "RX") ? true : false;
// outputs
for (quint8 i = 0; i < 8; ++i) {
num = QString::number(i+1);
map = settings->value("Output/sim_channel_" + num).toString();
outputMap[i] = channels.value(map, outputMap.at(i));
}
QString takeFrom = settings->value("Output/take_from", "TX").toString();
takeFromTX = (takeFrom == "TX") ? true : false;
// video
quint8 resolutionNum = settings->value("Video/number_of_resolutions", 0).toInt();
if (resolutionNum > 0) {
videoModes.clear();
videoModes << resolutionNum;
for (quint8 i = 0; i < resolutionNum; ++i) {
num = QString::number(i+1);
QString modes = settings->value("Video/resolution_" + num, "0, 0, 640, 480").toString();
QString mode;
foreach (mode, modes.split(" "))
videoModes << mode.toInt();
}
}
}

View File

@ -0,0 +1,67 @@
/**
******************************************************************************
*
* @file settings.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy 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 SETTINGS_H
#define SETTINGS_H
#include <QObject>
#include <QSettings>
#include <QHash>
#include <QList>
#include <QStringList>
#include <QDebug>
class Settings : public QObject
{
public:
explicit Settings(QString settingsPath, QObject *parent = 0);
void read();
QString remoteHost() { return sendToHost; }
quint16 remotePort() { return sendToPort; }
QString localHost() { return listenOnHost; }
quint16 localPort() { return listenOnPort; }
QList<quint8> getInputMap() { return inputMap; }
QList<quint8> getOutputMap() { return outputMap; }
bool isToRX() { return sendToRX; }
bool isFromTX() { return takeFromTX; }
QList<quint16> getVideoModes() { return videoModes; }
private:
QHash<QString, quint8> channels;
QSettings *settings;
QString sendToHost;
quint16 sendToPort;
QString listenOnHost;
quint16 listenOnPort;
QList<quint8> inputMap;
QList<quint8> outputMap;
bool sendToRX;
bool takeFromTX;
QList<quint16> videoModes;
};
#endif // SETTINGS_H

View File

@ -0,0 +1,228 @@
/**
******************************************************************************
*
* @file udpconnect.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy 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 "udpconnect.h"
#include "enums.h"
UdpSender::UdpSender(const QList<quint8> map,
bool isTX,
QObject *parent)
: QObject(parent)
{
qDebug() << this << "UdpSender::UdpSender thread:" << thread();
outSocket = NULL;
for (int i = 0; i < 8; ++i)
channels << 0.0;
channelsMap = map;
takeFromTX = isTX;
packetsSended = 0;
}
UdpSender::~UdpSender()
{
qDebug() << this << "UdpSender::~UdpSender";
if (outSocket)
delete outSocket;
}
// public
void UdpSender::init(const QString &remoteHost, quint16 remotePort)
{
qDebug() << this << "UdpSender::init";
outHost = remoteHost;
outPort = remotePort;
outSocket = new QUdpSocket();
}
void UdpSender::sendDatagram(const simToPlugin *stp)
{
QByteArray data;
data.resize(188);
QDataStream out(&data, QIODevice::WriteOnly);
out.setFloatingPointPrecision(QDataStream::SinglePrecision);
// magic header, "AERO"
out << quint32(0x4153494D);
// simulation step
out << stp->simTimeStep;
// home location
out << stp->initPosX << stp->initPosY << stp->initPosZ;
out << stp->wpHomeX << stp->wpHomeY << stp->wpHomeLat << stp->wpHomeLong;
// position
out << stp->posX << stp->posY << stp->posZ;
// velocity (world)
out << stp->velX << stp->velY << stp->velZ;
// angular velocity (model)
out << stp->angVelXm << stp->angVelYm << stp->angVelZm;
// acceleration (model)
out << stp->accelXm << stp->accelYm << stp->accelZm;
// coordinates
out << stp->latitude << stp->longitude;
// sonar
out << stp->AGL;
// attitude
out << stp->heading << stp->pitch << stp->roll;
// electric
out << stp->voltage << stp->current;
// matrix
out << stp->axisXx << stp->axisXy << stp->axisXz;
out << stp->axisYx << stp->axisYy << stp->axisYz;
out << stp->axisZx << stp->axisZy << stp->axisZz;
// channels
for (int i = 0; i < 8; ++i) {
quint8 mapTo = channelsMap.at(i);
if (mapTo == 255) // unused channel
out << 0.0;
else if (takeFromTX) // use values from simulators transmitter
out << stp->chSimTX[mapTo];
else // direct use values from ESC/motors/ailerons/etc
out << stp->chSimRX[mapTo];
}
// packet counter
out << packetsSended;
outSocket->writeDatagram(data, outHost, outPort);
++packetsSended;
}
//-----------------------------------------------------------------------------
UdpReceiver::UdpReceiver(const QList<quint8> map,
bool isRX,
QObject *parent)
: QThread(parent)
{
qDebug() << this << "UdpReceiver::UdpReceiver thread:" << thread();
stopped = false;
inSocket = NULL;
for (int i = 0; i < 10; ++i)
channels << -1.0;
channelsMap = map;
sendToRX = isRX;
armed = 0;
mode = 0;
packetsRecived = 1;
}
UdpReceiver::~UdpReceiver()
{
qDebug() << this << "UdpReceiver::~UdpReceiver";
if (inSocket)
delete inSocket;
}
// public
void UdpReceiver::init(const QString &localHost, quint16 localPort)
{
qDebug() << this << "UdpReceiver::init";
inSocket = new QUdpSocket();
qDebug() << this << "inSocket constructed" << inSocket->thread();
inSocket->bind(QHostAddress(localHost), localPort);
}
void UdpReceiver::run()
{
qDebug() << this << "UdpReceiver::run start";
while (!stopped)
onReadyRead();
qDebug() << this << "UdpReceiver::run ended";
}
void UdpReceiver::stop()
{
qDebug() << this << "UdpReceiver::stop";
stopped = true;
}
void UdpReceiver::setChannels(pluginToSim *pts)
{
QMutexLocker locker(&mutex);
for (int i = 0; i < 10; ++i) {
quint8 mapTo = channelsMap.at(i);
if (mapTo != 255) {
float channelValue = qBound(-1.0f, channels.at(i), 1.0f);
if (sendToRX) {
// direct connect to ESC/motors/ailerons/etc
pts->chNewRX[mapTo] = channelValue;
pts->chOverRX[mapTo] = true;
} else {
// replace simulators transmitter
pts->chNewTX[mapTo] = channelValue;
pts->chOverTX[mapTo] = true;
}
}
}
}
void UdpReceiver::getFlighStatus(quint8 &arm, quint8 &mod)
{
QMutexLocker locker(&mutex);
arm = armed;
mod = mode;
}
// private
void UdpReceiver::onReadyRead()
{
if (!inSocket->waitForReadyRead(8)) // 1/60fps ~= 16.7ms, 1/120fps ~= 8.3ms
return;
// TODO: add failsafe
// if a command not recieved then slowly return all channel to neutral
//
while (inSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(inSocket->pendingDatagramSize());
quint64 datagramSize;
datagramSize = inSocket->readDatagram(datagram.data(), datagram.size());
processDatagram(datagram);
}
}
void UdpReceiver::processDatagram(QByteArray &datagram)
{
QDataStream stream(datagram);
stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
// check magic header
quint32 magic;
stream >> magic;
if (magic != 0x52434D44) // "RCMD"
return;
// read channels
for (int i = 0; i < 10; ++i)
stream >> channels[i];
// read flight mode
stream >> armed >> mode;
// read counter
stream >> packetsRecived;
}

View File

@ -0,0 +1,90 @@
/**
******************************************************************************
*
* @file udpconnect.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy 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 UDPCONNECT_H
#define UDPCONNECT_H
#include <QObject>
#include <QUdpSocket>
#include <QList>
#include <QTime>
#include <QMutex>
#include <QMutexLocker>
#include "aerosimrcdatastruct.h"
class UdpSender : public QObject
{
// Q_OBJECT
public:
explicit UdpSender(const QList<quint8> map, bool isTX, QObject *parent = 0);
~UdpSender();
void init(const QString &remoteHost, quint16 remotePort);
void sendDatagram(const simToPlugin *stp);
quint32 pcks() { return packetsSended; }
private:
QUdpSocket *outSocket;
QHostAddress outHost;
quint16 outPort;
QList<float> channels;
QList<quint8> channelsMap;
bool takeFromTX;
quint32 packetsSended;
};
class UdpReceiver : public QThread
{
// Q_OBJECT
public:
explicit UdpReceiver(const QList<quint8> map, bool isRX, QObject *parent = 0);
~UdpReceiver();
void init(const QString &localHost, quint16 localPort);
void run();
void stop();
// function getChannels for other threads
void setChannels(pluginToSim *pts);
void getFlighStatus(quint8 &arm, quint8 &mod);
quint8 getArmed() { return armed; }
quint8 getMode() { return mode; }
quint32 pcks() { return packetsRecived; }
private:
volatile bool stopped;
QMutex mutex;
QUdpSocket *inSocket;
QList<float> channels;
QList<quint8> channelsMap;
bool sendToRX;
quint8 armed;
quint8 mode;
quint32 packetsRecived;
void onReadyRead();
void processDatagram(QByteArray &datagram);
};
#endif // UDPCONNECT_H

View File

@ -0,0 +1,17 @@
include(../../../../../openpilotgcs.pri)
QT += core gui network
TEMPLATE = app
TARGET = udp_test
DESTDIR = $$GCS_APP_PATH
HEADERS += \
udptestwidget.h
SOURCES += \
udptestmain.cpp \
udptestwidget.cpp
FORMS += \
udptestwidget.ui

View File

@ -0,0 +1,38 @@
/**
******************************************************************************
*
* @file udptestmain.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy plugin test utility
*****************************************************************************/
/*
* 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 <QApplication>
#include "udptestwidget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}

View File

@ -0,0 +1,537 @@
/**
******************************************************************************
*
* @file udptestwidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy plugin test utility
*****************************************************************************/
/*
* 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 "udptestwidget.h"
#include "ui_udptestwidget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
inSocket = NULL;
outSocket = NULL;
screenTimeout.start();
packetCounter = 0;
autoSendTimer = new QTimer(this);
connect(autoSendTimer, SIGNAL(timeout()), this, SLOT(sendDatagram()), Qt::DirectConnection);
}
Widget::~Widget()
{
if(outSocket) {
delete outSocket;
}
if(inSocket) {
delete inSocket;
}
delete ui;
}
// private slots //////////////////////////////////////////////////////////////
void Widget::on_btReciveStart_clicked()
{
on_btReciveStop_clicked();
inSocket = new QUdpSocket();
QString host = ui->localHost->text();
quint16 port = ui->localPort->text().toInt();
if (inSocket->bind(QHostAddress(host), port)) {
connect(inSocket, SIGNAL(readyRead()),
this, SLOT(readDatagram()), Qt::DirectConnection);
ui->listWidget->addItem("bind ok");
ui->btReciveStop->setEnabled(1);
ui->localHost->setDisabled(1);
ui->localPort->setDisabled(1);
ui->btReciveStart->setDisabled(1);
} else {
ui->listWidget->addItem("bind error: " + inSocket->errorString());
}
}
void Widget::on_btReciveStop_clicked()
{
if(inSocket) {
delete inSocket;
inSocket = NULL;
ui->listWidget->addItem("unbind ok");
} else {
ui->listWidget->addItem("socket not found");
}
ui->btReciveStart->setEnabled(1);
ui->localHost->setEnabled(1);
ui->localPort->setEnabled(1);
ui->btReciveStop->setDisabled(1);
}
void Widget::on_btTransmitStart_clicked()
{
on_btTransmitStop_clicked();
outSocket = new QUdpSocket();
outHost = ui->simHost->text();
outPort = ui->simPort->text().toInt();
ui->listWidget->addItem("transmit started");
ui->btTransmitStop->setEnabled(1);
ui->simHost->setDisabled(1);
ui->simPort->setDisabled(1);
ui->btTransmitStart->setDisabled(1);
}
void Widget::on_btTransmitStop_clicked()
{
if(outSocket) {
delete outSocket;
outSocket = NULL;
ui->listWidget->addItem("transmit stopped");
} else {
ui->listWidget->addItem("transmit socket not found");
}
ui->btTransmitStart->setEnabled(1);
ui->simHost->setEnabled(1);
ui->simPort->setEnabled(1);
ui->btTransmitStop->setDisabled(1);
}
void Widget::readDatagram()
{
while (inSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(inSocket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
quint64 datagramSize = inSocket->readDatagram(datagram.data(), datagram.size(),
&sender, &senderPort);
Q_UNUSED(datagramSize);
processDatagram(datagram);
if (ui->autoAnswer->isChecked())
sendDatagram();
}
}
// private ////////////////////////////////////////////////////////////////////
void Widget::processDatagram(const QByteArray &data)
{
QByteArray buf = data;
QDataStream stream(&buf, QIODevice::ReadOnly);
stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
// check magic header
quint32 magic;
stream >> magic;
if (magic == 0x4153494D) { // "AERO"
float timeStep,
homeX, homeY, homeZ,
WpHX, WpHY, WpLat, WpLon,
posX, posY, posZ,
velX, velY, velZ,
angX, angY, angZ,
accX, accY, accZ,
lat, lon, alt,
head, pitch, roll,
volt, curr,
rx, ry, rz, fx, fy, fz, ux, uy, uz,
chAil, chEle, chThr, chRud, chPlg1, chPlg2, chFpv1, chFpv2;
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 >> alt;
stream >> head >> pitch >> roll;
stream >> volt >> curr;
stream >> rx >> ry >> rz >> fx >> fy >> fz >> ux >> uy >> uz;
stream >> chAil >> chEle >> chThr >> chRud >> chPlg1 >> chPlg2 >> chFpv1 >> chFpv2;
stream >> packetCounter;
if(ui->tabWidget->currentIndex() != 0)
return;
if (screenTimeout.elapsed() < 200)
return;
ui->listWidget->clear();
/*
ui->listWidget->addItem("time step (s)");
ui->listWidget->addItem(QString("%1")
.arg(timeStep);
ui->listWidget->addItem("home location (m)");
ui->listWidget->addItem(QString("%1, %2, %3")
.arg(homeX, 7, 'f', 4)
.arg(homeY, 7, 'f', 4)
.arg(homeZ, 7, 'f', 4));
ui->listWidget->addItem("home waypoint");
ui->listWidget->addItem(QString("%1, %2, %3, %4")
.arg(WpHX, 7, 'f', 4)
.arg(WpHY, 7, 'f', 4)
.arg(WpLat, 7, 'f', 4)
.arg(WpLon, 7, 'f', 4));
ui->listWidget->addItem("model position (m)");
ui->listWidget->addItem(QString("%1, %2, %3")
.arg(posX, 7, 'f', 4)
.arg(posY, 7, 'f', 4)
.arg(posZ, 7, 'f', 4));
ui->listWidget->addItem("model velocity (m/s)");
ui->listWidget->addItem(QString("%1, %2, %3")
.arg(velX, 7, 'f', 4)
.arg(velY, 7, 'f', 4)
.arg(velZ, 7, 'f', 4));
ui->listWidget->addItem("model angular velocity (rad/s)");
ui->listWidget->addItem(QString("%1, %2, %3")
.arg(angX, 7, 'f', 4)
.arg(angY, 7, 'f', 4)
.arg(angZ, 7, 'f', 4));
ui->listWidget->addItem("model acceleration (m/s/s)");
ui->listWidget->addItem(QString("%1, %2, %3")
.arg(accX, 7, 'f', 4)
.arg(accY, 7, 'f', 4)
.arg(accZ, 7, 'f', 4));
ui->listWidget->addItem("model coordinates (deg, deg, m)");
ui->listWidget->addItem(QString("%1, %2, %3")
.arg(lat, 7, 'f', 4)
.arg(lon, 7, 'f', 4)
.arg(alt, 7, 'f', 4));
ui->listWidget->addItem("model electrics");
ui->listWidget->addItem(QString("%1V, %2A")
.arg(volt, 7, 'f', 4)
.arg(curr, 7, 'f', 4));
ui->listWidget->addItem("channels");
ui->listWidget->addItem(QString("%1 %2 %3 %4 %5 %6 %7 %8")
.arg(chAil, 6, 'f', 3)
.arg(chEle, 6, 'f', 3)
.arg(chThr, 6, 'f', 3)
.arg(chRud, 6, 'f', 3)
.arg(chPlg1, 6, 'f', 3)
.arg(chPlg2, 6, 'f', 3)
.arg(chFpv1, 6, 'f', 3)
.arg(chFpv2, 6, 'f', 3));
ui->listWidget->addItem("datagram size (bytes), packet counter");
ui->listWidget->addItem(QString("%1 %2")
.arg(data.size())
.arg(packetCounter));
*/
// matrix calculation start
// model matrix
QMatrix4x4 m = QMatrix4x4( fy, fx, -fz, 0.0,
ry, rx, -rz, 0.0,
-uy, -ux, uz, 0.0,
0.0, 0.0, 0.0, 1.0);
m.optimize();
// world matrix
QMatrix4x4 w = m.inverted();
// model quat
QQuaternion q;
asMatrix2Quat(m, q);
// model roll, pitch, yaw
QVector3D rpy;
asMatrix2RPY(m, rpy);
// sonar
float sAlt = 5.0;
if ((alt < (sAlt * 2.0)) && (roll < 0.35) && (pitch < 0.35)) {
float x = alt * qTan(roll);
float y = alt * qTan(pitch);
float h = QVector3D(x, y, alt).length();
sAlt = qMin(h, sAlt);
}
ui->listWidget->addItem("sonar altitude");
ui->listWidget->addItem(QString("%1")
.arg(sAlt, 8, 'f', 5));
ui->listWidget->addItem("vectors");
ui->listWidget->addItem(QString(" X Y Z"));
ui->listWidget->addItem(QString("R: %1 %2 %3\nF: %4 %5 %6\nU: %7 %8 %9")
.arg(rx, 8, 'f', 5).arg(ry, 8, 'f', 5).arg(rz, 8, 'f', 5)
.arg(fx, 8, 'f', 5).arg(fy, 8, 'f', 5).arg(fz, 8, 'f', 5)
.arg(ux, 8, 'f', 5).arg(uy, 8, 'f', 5).arg(uz, 8, 'f', 5));
ui->listWidget->addItem("CC model matrix");
ui->listWidget->addItem(QString(" %1 %2 %3\n %4 %5 %6\n %7 %8 %9")
.arg(m(0, 0), 8, 'f', 5).arg(m(0, 1), 8, 'f', 5).arg(m(0, 2), 8, 'f', 5)
.arg(m(1, 0), 8, 'f', 5).arg(m(1, 1), 8, 'f', 5).arg(m(1, 2), 8, 'f', 5)
.arg(m(2, 0), 8, 'f', 5).arg(m(2, 1), 8, 'f', 5).arg(m(2, 2), 8, 'f', 5));
ui->listWidget->addItem("CC world matrix");
ui->listWidget->addItem(QString(" %1 %2 %3\n %4 %5 %6\n %7 %8 %9")
.arg(w(0, 0), 8, 'f', 5).arg(w(0, 1), 8, 'f', 5).arg(w(0, 2), 8, 'f', 5)
.arg(w(1, 0), 8, 'f', 5).arg(w(1, 1), 8, 'f', 5).arg(w(1, 2), 8, 'f', 5)
.arg(w(2, 0), 8, 'f', 5).arg(w(2, 1), 8, 'f', 5).arg(w(2, 2), 8, 'f', 5));
ui->listWidget->addItem("CC quaternion");
ui->listWidget->addItem(QString("%1, %2, %3, %4")
.arg(q.x(), 7, 'f', 4)
.arg(q.y(), 7, 'f', 4)
.arg(q.z(), 7, 'f', 4)
.arg(q.scalar(), 7, 'f', 4));
ui->listWidget->addItem("model attitude (deg)");
ui->listWidget->addItem(QString("%1, %2, %3")
.arg(roll*RAD2DEG, 7, 'f', 4)
.arg(pitch*RAD2DEG, 7, 'f', 4)
.arg(head*RAD2DEG, 7, 'f', 4));
ui->listWidget->addItem("CC attitude calculated (deg)");
ui->listWidget->addItem(QString("%1, %2, %3")
.arg(rpy.x(), 7, 'f', 4)
.arg(rpy.y(), 7, 'f', 4)
.arg(rpy.z(), 7, 'f', 4));
screenTimeout.restart();
} else if (magic == 0x52434D44) { // "RCMD"
qreal ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10;
stream >> ch1 >> ch2 >> ch3 >> ch4 >> ch5 >> ch6 >> ch7 >> ch8 >> ch9 >> ch10;
quint8 armed, mode;
stream >> armed >> mode;
if(ui->tabWidget->currentIndex() == 0) {
if (screenTimeout.elapsed() < 200)
return;
ui->listWidget->clear();
ui->listWidget->addItem("channels");
ui->listWidget->addItem("CH1: " + QString::number(ch1));
ui->listWidget->addItem("CH2: " + QString::number(ch2));
ui->listWidget->addItem("CH3: " + QString::number(ch3));
ui->listWidget->addItem("CH4: " + QString::number(ch4));
ui->listWidget->addItem("CH5: " + QString::number(ch5));
ui->listWidget->addItem("CH6: " + QString::number(ch6));
ui->listWidget->addItem("CH7: " + QString::number(ch7));
ui->listWidget->addItem("CH8: " + QString::number(ch8));
ui->listWidget->addItem("CH9: " + QString::number(ch9));
ui->listWidget->addItem("CH10:" + QString::number(ch10));
ui->listWidget->addItem("armed:" + QString::number(armed));
ui->listWidget->addItem("fmode:" + QString::number(mode));
}
screenTimeout.restart();
} else {
qDebug() << "unknown magic:" << magic;
}
}
void Widget::sendDatagram()
{
if(!outSocket)
return;
float ch[10]; // = {0,0,0,0,0,0,0,0,0,0};
quint8 armed;
quint8 fmode;
const float coeff = 1.0 / 512.0;
ch[0] = ui->ch1->value() * coeff;
ch[1] = ui->ch2->value() * coeff;
ch[2] = ui->ch3->value() * coeff;
ch[3] = ui->ch4->value() * coeff;
ch[4] = ui->ch5->value() * coeff;
ch[5] = ui->ch6->value() * coeff;
ch[6] = ui->ch7->value() * coeff;
ch[7] = ui->ch8->value() * coeff;
ch[8] = ui->ch9->value() * coeff;
ch[9] = ui->ch10->value() * coeff;
armed = (ui->disarmed->isChecked()) ? 0 : (ui->arming->isChecked()) ? 1 : 2;
fmode = ui->flightMode->value();
QByteArray data;
// 50 - current size of values, 4(quint32) + 10*4(float) + 2*1(quint8) + 4(quint32)
data.resize(50);
QDataStream stream(&data, QIODevice::WriteOnly);
stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
// magic header, "RCMD"
stream << quint32(0x52434D44);
// send channels
for (int i = 0; i < 10; ++i) {
stream << ch[i];
}
// send armed and mode
stream << armed << fmode;
// send readed counter
stream << packetCounter;
if (outSocket->writeDatagram(data, outHost, outPort) == -1) {
qDebug() << "write failed: outHost" << outHost << " "
<< "outPort " << outPort << " "
<< outSocket->errorString();
}
}
void Widget::on_autoSend_clicked()
{
autoSendTimer->start(100);
qDebug() << "timer start";
}
void Widget::on_autoAnswer_clicked()
{
autoSendTimer->stop();
qDebug() << "timer stop";
}
// transfomations
void Widget::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 Widget::asQuat2RPY(const QQuaternion &q, QVector3D &rpy)
{
qreal roll;
qreal pitch;
qreal yaw;
const qreal d2 = 2.0;
const qreal qss = q.scalar() * q.scalar();
const qreal qxx = q.x() * q.x();
const qreal qyy = q.y() * q.y();
const qreal qzz = q.z() * q.z();
qreal test = -d2 * (q.x() * q.z() - q.scalar() * q.y());
if (qFabs(test) > 0.998) {
// ~86.3°, gimbal lock
qreal R10 = d2 * (q.x() * q.y() - q.scalar() * q.z());
qreal R11 = qss - qxx + qyy - qzz;
roll = 0.0;
pitch = copysign(M_PI_2, test);
yaw = qAtan2(-R10, R11);
} else {
qreal R12 = d2 * (q.y() * q.z() + q.scalar() * q.x());
qreal R22 = qss - qxx - qyy + qzz;
qreal R01 = d2 * (q.x() * q.y() + q.scalar() * q.z());
qreal R00 = qss + qxx - qyy - qzz;
roll = qAtan2(R12, R22);
pitch = qAsin(test);
yaw = qAtan2(R01, R00);
}
rpy.setX(RAD2DEG * roll);
rpy.setY(RAD2DEG * pitch);
rpy.setZ(RAD2DEG * yaw);
}
void Widget::asMatrix2RPY(const QMatrix4x4 &m, QVector3D &rpy)
{
qreal roll;
qreal pitch;
qreal 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);
}
/* // not used
void Widget::ccRPY2Quat(const QVector3D &rpy, QQuaternion &q)
{
float phi, theta, psi;
float cphi, sphi, ctheta, stheta, cpsi, spsi;
phi = rpy.x() / 2;
theta = rpy.y() / 2;
psi = rpy.z() / 2;
cphi = cosf(phi);
sphi = sinf(phi);
ctheta = cosf(theta);
stheta = sinf(theta);
cpsi = cosf(psi);
spsi = sinf(psi);
q.setScalar(cphi * ctheta * cpsi + sphi * stheta * spsi);
q.setX(sphi * ctheta * cpsi - cphi * stheta * spsi);
q.setY(cphi * stheta * cpsi + sphi * ctheta * spsi);
q.setZ(cphi * ctheta * spsi - sphi * stheta * cpsi);
if (q.scalar() < 0) { // q0 always positive for uniqueness
q.setScalar(-q.scalar());
q.setX(-q.x());
q.setY(-q.y());
q.setZ(-q.z());
}
}
void Widget::ccQuat2Matrix(const QQuaternion &q, QMatrix4x4 &m)
{
float q0s = q.scalar() * q.scalar();
float q1s = q.x() * q.x();
float q2s = q.y() * q.y();
float q3s = q.z() * q.z();
float m00 = q0s + q1s - q2s - q3s;
float m01 = 2 * (q.x() * q.y() + q.scalar() * q.z());
float m02 = 2 * (q.x() * q.z() - q.scalar() * q.y());
float m10 = 2 * (q.x() * q.y() - q.scalar() * q.z());
float m11 = q0s - q1s + q2s - q3s;
float m12 = 2 * (q.y() * q.z() + q.scalar() * q.x());
float m20 = 2 * (q.x() * q.z() + q.scalar() * q.y());
float m21 = 2 * (q.y() * q.z() - q.scalar() * q.x());
float m22 = q0s - q1s - q2s + q3s;
m = QMatrix4x4(m00, m01, m02, 0,
m10, m11, m12, 0,
m20, m21, m22, 0,
0, 0, 0, 1);
}
*/

View File

@ -0,0 +1,91 @@
/**
******************************************************************************
*
* @file udptestwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup 3rdParty Third-party integration
* @{
* @addtogroup AeroSimRC AeroSimRC proxy plugin
* @{
* @brief AeroSimRC simulator to HITL proxy plugin test utility
*****************************************************************************/
/*
* 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 UDPTESTWIDGET_H
#define UDPTESTWIDGET_H
#include <QWidget>
#include <QUdpSocket>
#include <QTime>
#include <qmath.h>
#include <QVector3D>
#include <QMatrix4x4>
#include <QDebug>
#include <QTimer>
namespace Ui {
class Widget;
}
const float RAD2DEG = (float)(180.0/M_PI);
const float DEG2RAD = (float)(M_PI/180.0);
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_btReciveStart_clicked();
void on_btReciveStop_clicked();
void on_btTransmitStart_clicked();
void on_btTransmitStop_clicked();
void readDatagram();
void sendDatagram();
void on_autoSend_clicked();
void on_autoAnswer_clicked();
private:
Ui::Widget *ui;
QTime screenTimeout;
QUdpSocket *inSocket;
QUdpSocket *outSocket;
QHostAddress outHost;
quint16 outPort;
quint32 packetCounter;
void processDatagram(const QByteArray &data);
QTimer *autoSendTimer;
void asMatrix2Quat(const QMatrix4x4 &m, QQuaternion &q);
void asMatrix2RPY(const QMatrix4x4 &m, QVector3D &rpy);
void asQuat2RPY(const QQuaternion &q, QVector3D &rpy);
/* // not used
* void ccRPY2Quat(const QVector3D &rpy, QQuaternion &q);
* void ccQuat2Matrix(const QQuaternion &q, QMatrix4x4 &m);
*/
};
#endif // UDPTESTWIDGET_H

View File

@ -0,0 +1,940 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>440</width>
<height>525</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">udp_test</string>
</property>
<property name="windowFilePath">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="4">
<widget class="QPushButton" name="btReciveStart">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">Connect</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLineEdit" name="localPort">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">40100</string>
</property>
<property name="maxLength">
<number>5</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="localHost">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">127.0.0.1</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lbLocalHost">
<property name="text">
<string notr="true">sim host</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lbSimHost">
<property name="text">
<string notr="true">local host:</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="lbSimPort">
<property name="text">
<string notr="true">local port:</string>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QPushButton" name="btReciveStop">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">Disconnect</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="simHost">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">127.0.0.1</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="lbLocalPort">
<property name="text">
<string notr="true">sim port</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLineEdit" name="simPort">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">40200</string>
</property>
<property name="maxLength">
<number>5</number>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QPushButton" name="btTransmitStart">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">Transmit</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QPushButton" name="btTransmitStop">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">Stop</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_1">
<attribute name="title">
<string notr="true">raw data</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QListWidget" name="listWidget">
<property name="font">
<font>
<family>Terminal</family>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string notr="true">channels</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>send data</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QRadioButton" name="autoAnswer">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string notr="true">answer on recieve</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="autoSend">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string notr="true">auto send</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Flight mode</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QSlider" name="flightMode">
<property name="maximum">
<number>6</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Armed state</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QRadioButton" name="disarmed">
<property name="text">
<string>Disarmed</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="arming">
<property name="text">
<string>Arming</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="armed">
<property name="text">
<string>Armed</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Channels</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="lbCH1n">
<property name="text">
<string notr="true">CH1</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="ch1">
<property name="minimum">
<number>-511</number>
</property>
<property name="maximum">
<number>512</number>
</property>
<property name="singleStep">
<number>16</number>
</property>
<property name="pageStep">
<number>32</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>128</number>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="lbCH1">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">0</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lbCH2n">
<property name="text">
<string notr="true">CH2</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSlider" name="ch2">
<property name="minimum">
<number>-511</number>
</property>
<property name="maximum">
<number>512</number>
</property>
<property name="singleStep">
<number>16</number>
</property>
<property name="pageStep">
<number>32</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>128</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="lbCH2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">0</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lbCH3n">
<property name="text">
<string notr="true">CH3</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="ch3">
<property name="minimum">
<number>-511</number>
</property>
<property name="maximum">
<number>512</number>
</property>
<property name="singleStep">
<number>16</number>
</property>
<property name="pageStep">
<number>32</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>128</number>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="lbCH3">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">0</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lbCH4n">
<property name="text">
<string notr="true">CH4</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSlider" name="ch4">
<property name="minimum">
<number>-511</number>
</property>
<property name="maximum">
<number>512</number>
</property>
<property name="singleStep">
<number>16</number>
</property>
<property name="pageStep">
<number>32</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>128</number>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="lbCH4">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">0</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="lbCH5n">
<property name="text">
<string notr="true">CH5</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSlider" name="ch5">
<property name="minimum">
<number>-511</number>
</property>
<property name="maximum">
<number>512</number>
</property>
<property name="singleStep">
<number>16</number>
</property>
<property name="pageStep">
<number>32</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>128</number>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="lbCH5">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">0</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="lbCH6n">
<property name="text">
<string notr="true">CH6</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="lbCH6">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">0</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="lbCH7n">
<property name="text">
<string notr="true">Ch7</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="lbCH7">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">0</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="lbCH8n">
<property name="text">
<string notr="true">Ch8</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QLabel" name="lbCH8">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">0</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="lbCH9n">
<property name="text">
<string notr="true">Ch9</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QSlider" name="ch9">
<property name="minimum">
<number>-511</number>
</property>
<property name="maximum">
<number>512</number>
</property>
<property name="singleStep">
<number>16</number>
</property>
<property name="pageStep">
<number>32</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>128</number>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QLabel" name="lbCH9">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">0</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="lbCH10n">
<property name="text">
<string notr="true">Ch10</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QSlider" name="ch10">
<property name="minimum">
<number>-511</number>
</property>
<property name="maximum">
<number>512</number>
</property>
<property name="singleStep">
<number>16</number>
</property>
<property name="pageStep">
<number>32</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>128</number>
</property>
</widget>
</item>
<item row="9" column="2">
<widget class="QLabel" name="lbCH10">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">0</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSlider" name="ch6">
<property name="minimum">
<number>-511</number>
</property>
<property name="maximum">
<number>512</number>
</property>
<property name="singleStep">
<number>16</number>
</property>
<property name="pageStep">
<number>32</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>128</number>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QSlider" name="ch7">
<property name="minimum">
<number>-511</number>
</property>
<property name="maximum">
<number>512</number>
</property>
<property name="singleStep">
<number>16</number>
</property>
<property name="pageStep">
<number>32</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>128</number>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QSlider" name="ch8">
<property name="minimum">
<number>-511</number>
</property>
<property name="maximum">
<number>512</number>
</property>
<property name="singleStep">
<number>16</number>
</property>
<property name="pageStep">
<number>32</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>128</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

View File

@ -1,27 +1,5 @@
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
TEMPLATE = subdirs
SUBDIRS = plugin aerosimrc
plugin.file = plugin.pro

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file hitlconfiguration.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file hitlv2configuration.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file hitlconfiguration.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file hitlv2configuration.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file hitlfactory.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file hitlv2factory.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -24,6 +24,7 @@
* 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"

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file hitlfactory.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file hitlv2factory.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file hitl.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file hitlv2gadget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -24,6 +24,7 @@
* 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"

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file hitl.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file hitlv2gadget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file hitloptionspage.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file hitlv2optionspage.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file hitloptionspage.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file hitlv2optionspage.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file mapplugin.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file hitlv2plugin.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -24,6 +24,7 @@
* 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>

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file browserplugin.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file hitlv2plugin.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file hitlwidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file hitlv2widget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -24,6 +24,7 @@
* 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>

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file hitlwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file hitlv2widget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify

View File

@ -0,0 +1,32 @@
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
FORMS += \
hitlv2optionspage.ui \
hitlv2widget.ui
OTHER_FILES += hitlv2.pluginspec

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file simulator.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file simulatorv2.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file simulator.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file simulatorv2.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup HITLPlugin HITL Plugin
* @addtogroup HITLPlugin HITLv2 Plugin
* @{
* @brief The Hardware In The Loop plugin
* @brief The Hardware In The Loop plugin version 2
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify

View File

@ -112,327 +112,370 @@ void UAVObjectField::limitsInitialize(const QString &limits)
QStringList stringPerElement=limits.split(",");
quint32 index=0;
foreach (QString str, stringPerElement) {
QString _str=str.trimmed();
QStringList valuesPerElement=_str.split(":");
LimitStruct lstruc;
bool b1=valuesPerElement.at(0).startsWith("%");
bool b2=(int)(index)<(int)numElements;
if(b1 && b2)
QStringList ruleList=str.split(";");
QList<LimitStruct> limitList;
foreach(QString rule,ruleList)
{
if(valuesPerElement.at(0).right(2)=="EQ")
lstruc.type=EQUAL;
else if(valuesPerElement.at(0).right(2)=="NE")
lstruc.type=NOT_EQUAL;
else if(valuesPerElement.at(0).right(2)=="BE")
lstruc.type=BETWEEN;
else if(valuesPerElement.at(0).right(2)=="BI")
lstruc.type=BIGGER;
else if(valuesPerElement.at(0).right(2)=="SM")
lstruc.type=SMALLER;
else
qDebug()<<"limits parsing failed (invalid property) on UAVObjectField"<<name;
valuesPerElement.removeAt(0);
foreach(QString _value,valuesPerElement)
QString _str=rule.trimmed();
if(_str.isEmpty())
continue;
QStringList valuesPerElement=_str.split(":");
LimitStruct lstruc;
bool b1=valuesPerElement.at(0).startsWith("%");
bool b2=(int)(index)<(int)numElements;
bool b3=valuesPerElement.at(0).size()==3;
bool auxb;
valuesPerElement.at(0).mid(1,4).toInt(&auxb,16);
bool b4=((valuesPerElement.at(0).size())==7 && auxb);
if(b1 && b2 && (b3 || b4))
{
QString value=_value.trimmed();
switch (type)
if(b4)
lstruc.board=valuesPerElement.at(0).mid(1,4).toInt(&auxb,16);
else
lstruc.board=0;
if(valuesPerElement.at(0).right(2)=="EQ")
lstruc.type=EQUAL;
else if(valuesPerElement.at(0).right(2)=="NE")
lstruc.type=NOT_EQUAL;
else if(valuesPerElement.at(0).right(2)=="BE")
lstruc.type=BETWEEN;
else if(valuesPerElement.at(0).right(2)=="BI")
lstruc.type=BIGGER;
else if(valuesPerElement.at(0).right(2)=="SM")
lstruc.type=SMALLER;
else
qDebug()<<"limits parsing failed (invalid property) on UAVObjectField"<<name;
valuesPerElement.removeAt(0);
foreach(QString _value,valuesPerElement)
{
case UINT8:
case UINT16:
case UINT32:
case BITFIELD:
lstruc.values.append((quint32)value.toULong());
break;
case INT8:
case INT16:
case INT32:
lstruc.values.append((qint32)value.toLong());
break;
case FLOAT32:
lstruc.values.append((float)value.toFloat());
break;
case ENUM:
lstruc.values.append((QString)value);
break;
case STRING:
lstruc.values.append((QString)value);
break;
default:
lstruc.values.append(QVariant());
QString value=_value.trimmed();
switch (type)
{
case UINT8:
case UINT16:
case UINT32:
case BITFIELD:
lstruc.values.append((quint32)value.toULong());
break;
case INT8:
case INT16:
case INT32:
lstruc.values.append((qint32)value.toLong());
break;
case FLOAT32:
lstruc.values.append((float)value.toFloat());
break;
case ENUM:
lstruc.values.append((QString)value);
break;
case STRING:
lstruc.values.append((QString)value);
break;
default:
lstruc.values.append(QVariant());
}
}
limitList.append(lstruc);
}
else
{
if(!valuesPerElement.at(0).isEmpty() && !b1)
qDebug()<<"limits parsing failed (property doesn't start with %) on UAVObjectField"<<name;
else if(!b2)
qDebug()<<"limits parsing failed (index>numelements) on UAVObjectField"<<name<<"index"<<index<<"numElements"<<numElements;
else if(!b3 || !b4 )
qDebug()<<"limits parsing failed limit not starting with %XX or %YYYYXX where XX is the limit type and YYYY is the board type on UAVObjectField"<<name;
}
elementLimits.insert(index,lstruc);
++index;
}
else
elementLimits.insert(index,limitList);
++index;
}
foreach(QList<LimitStruct> limitList,elementLimits)
{
foreach(LimitStruct limit,limitList)
{
if(!valuesPerElement.at(0).isEmpty() && !b1)
qDebug()<<"limits parsing failed (property doesn't start with %) on UAVObjectField"<<name;
else if(!b2)
qDebug()<<"limits parsing failed (index>numelements) on UAVObjectField"<<name<<"index"<<index<<"numElements"<<numElements;
qDebug()<<"Limit type"<<limit.type<<"for board"<<limit.board<<"for field"<<getName();
foreach(QVariant var,limit.values)
{
qDebug()<<"value"<<var;
}
}
}
}
bool UAVObjectField::isWithinLimits(QVariant var,quint32 index)
bool UAVObjectField::isWithinLimits(QVariant var,quint32 index, int board)
{
if(!elementLimits.keys().contains(index))
return true;
LimitStruct struc=elementLimits.value(index);
switch(struc.type)
foreach(LimitStruct struc,elementLimits.value(index))
{
case EQUAL:
switch (type)
if((struc.board!=board) && board!=0 && struc.board!=0)
continue;
switch(struc.type)
{
case INT8:
case INT16:
case INT32:
foreach (QVariant vars, struc.values) {
if(var.toInt()==vars.toInt())
return true;
case EQUAL:
switch (type)
{
case INT8:
case INT16:
case INT32:
foreach (QVariant vars, struc.values) {
if(var.toInt()==vars.toInt())
return true;
}
return false;
break;
case UINT8:
case UINT16:
case UINT32:
case BITFIELD:
foreach (QVariant vars, struc.values) {
if(var.toUInt()==vars.toUInt())
return true;
}
return false;
break;
case ENUM:
case STRING:
foreach (QVariant vars, struc.values) {
if(var.toString()==vars.toString())
return true;
}
return false;
break;
case FLOAT32:
foreach (QVariant vars, struc.values) {
if(var.toFloat()==vars.toFloat())
return true;
}
return false;
break;
default:
return true;
}
return false;
break;
case UINT8:
case UINT16:
case UINT32:
case BITFIELD:
foreach (QVariant vars, struc.values) {
if(var.toUInt()==vars.toUInt())
return true;
case NOT_EQUAL:
switch (type)
{
case INT8:
case INT16:
case INT32:
foreach (QVariant vars, struc.values) {
if(var.toInt()==vars.toInt())
return false;
}
return true;
break;
case UINT8:
case UINT16:
case UINT32:
case BITFIELD:
foreach (QVariant vars, struc.values) {
if(var.toUInt()==vars.toUInt())
return false;
}
return true;
break;
case ENUM:
case STRING:
foreach (QVariant vars, struc.values) {
if(var.toString()==vars.toString())
return false;
}
return true;
break;
case FLOAT32:
foreach (QVariant vars, struc.values) {
if(var.toFloat()==vars.toFloat())
return false;
}
return true;
break;
default:
return true;
}
return false;
break;
case ENUM:
case STRING:
foreach (QVariant vars, struc.values) {
if(var.toString()==vars.toString())
return true;
case BETWEEN:
if(struc.values.length()<2)
{
qDebug()<<__FUNCTION__<<"between limit with less than 1 pair, aborting; field:"<<name;
return true;
}
return false;
break;
case FLOAT32:
foreach (QVariant vars, struc.values) {
if(var.toFloat()==vars.toFloat())
return true;
if(struc.values.length()>2)
qDebug()<<__FUNCTION__<<"between limit with more than 1 pair, using first; field"<<name;
switch (type)
{
case INT8:
case INT16:
case INT32:
if(!(var.toInt()>=struc.values.at(0).toInt() && var.toInt()<=struc.values.at(1).toInt()))
return false;
return true;
break;
case UINT8:
case UINT16:
case UINT32:
case BITFIELD:
if(!(var.toUInt()>=struc.values.at(0).toUInt() && var.toUInt()<=struc.values.at(1).toUInt()))
return false;
return true;
break;
case ENUM:
if(!(options.indexOf(var.toString())>=options.indexOf(struc.values.at(0).toString()) && options.indexOf(var.toString())<=options.indexOf(struc.values.at(1).toString())))
return false;
return true;
break;
case STRING:
return true;
break;
case FLOAT32:
if(!(var.toFloat()>=struc.values.at(0).toFloat() && var.toFloat()<=struc.values.at(1).toFloat()))
return false;
return true;
break;
default:
return true;
}
return false;
break;
default:
return true;
}
break;
case NOT_EQUAL:
switch (type)
{
case INT8:
case INT16:
case INT32:
foreach (QVariant vars, struc.values) {
if(var.toInt()==vars.toInt())
return false;
case BIGGER:
if(struc.values.length()<1)
{
qDebug()<<__FUNCTION__<<"BIGGER limit with less than 1 value, aborting; field:"<<name;
return true;
}
return true;
break;
case UINT8:
case UINT16:
case UINT32:
case BITFIELD:
foreach (QVariant vars, struc.values) {
if(var.toUInt()==vars.toUInt())
return false;
if(struc.values.length()>1)
qDebug()<<__FUNCTION__<<"BIGGER limit with more than 1 value, using first; field"<<name;
switch (type)
{
case INT8:
case INT16:
case INT32:
if(!(var.toInt()>=struc.values.at(0).toInt()))
return false;
return true;
break;
case UINT8:
case UINT16:
case UINT32:
case BITFIELD:
if(!(var.toUInt()>=struc.values.at(0).toUInt()))
return false;
return true;
break;
case ENUM:
if(!(options.indexOf(var.toString())>=options.indexOf(struc.values.at(0).toString())))
return false;
return true;
break;
case STRING:
return true;
break;
case FLOAT32:
if(!(var.toFloat()>=struc.values.at(0).toFloat()))
return false;
return true;
break;
default:
return true;
}
return true;
break;
case ENUM:
case STRING:
foreach (QVariant vars, struc.values) {
if(var.toString()==vars.toString())
return false;
case SMALLER:
switch (type)
{
case INT8:
case INT16:
case INT32:
if(!(var.toInt()<=struc.values.at(0).toInt()))
return false;
return true;
break;
case UINT8:
case UINT16:
case UINT32:
case BITFIELD:
if(!(var.toUInt()<=struc.values.at(0).toUInt()))
return false;
return true;
break;
case ENUM:
if(!(options.indexOf(var.toString())<=options.indexOf(struc.values.at(0).toString())))
return false;
return true;
break;
case STRING:
return true;
break;
case FLOAT32:
if(!(var.toFloat()<=struc.values.at(0).toFloat()))
return false;
return true;
break;
default:
return true;
}
return true;
break;
case FLOAT32:
foreach (QVariant vars, struc.values) {
if(var.toFloat()==vars.toFloat())
return false;
}
return true;
break;
default:
return true;
}
break;
case BETWEEN:
if(struc.values.length()<2)
{
qDebug()<<__FUNCTION__<<"between limit with less than 1 pair, aborting; field:"<<name;
return true;
}
if(struc.values.length()>2)
qDebug()<<__FUNCTION__<<"between limit with more than 1 pair, using first; field"<<name;
switch (type)
{
case INT8:
case INT16:
case INT32:
if(!(var.toInt()>=struc.values.at(0).toInt() && var.toInt()<=struc.values.at(1).toInt()))
return false;
return true;
break;
case UINT8:
case UINT16:
case UINT32:
case BITFIELD:
if(!(var.toUInt()>=struc.values.at(0).toUInt() && var.toUInt()<=struc.values.at(1).toUInt()))
return false;
return true;
break;
case ENUM:
if(!(options.indexOf(var.toString())>=options.indexOf(struc.values.at(0).toString()) && options.indexOf(var.toString())<=options.indexOf(struc.values.at(1).toString())))
return false;
return true;
break;
case STRING:
return true;
break;
case FLOAT32:
if(!(var.toFloat()>=struc.values.at(0).toFloat() && var.toFloat()<=struc.values.at(1).toFloat()))
return false;
return true;
break;
default:
return true;
}
break;
case BIGGER:
if(struc.values.length()<1)
{
qDebug()<<__FUNCTION__<<"BIGGER limit with less than 1 value, aborting; field:"<<name;
return true;
}
if(struc.values.length()>1)
qDebug()<<__FUNCTION__<<"BIGGER limit with more than 1 value, using first; field"<<name;
switch (type)
{
case INT8:
case INT16:
case INT32:
if(!(var.toInt()>=struc.values.at(0).toInt()))
return false;
return true;
break;
case UINT8:
case UINT16:
case UINT32:
case BITFIELD:
if(!(var.toUInt()>=struc.values.at(0).toUInt()))
return false;
return true;
break;
case ENUM:
if(!(options.indexOf(var.toString())>=options.indexOf(struc.values.at(0).toString())))
return false;
return true;
break;
case STRING:
return true;
break;
case FLOAT32:
if(!(var.toFloat()>=struc.values.at(0).toFloat()))
return false;
return true;
break;
default:
return true;
}
break;
case SMALLER:
switch (type)
{
case INT8:
case INT16:
case INT32:
if(!(var.toInt()<=struc.values.at(0).toInt()))
return false;
return true;
break;
case UINT8:
case UINT16:
case UINT32:
case BITFIELD:
if(!(var.toUInt()<=struc.values.at(0).toUInt()))
return false;
return true;
break;
case ENUM:
if(!(options.indexOf(var.toString())<=options.indexOf(struc.values.at(0).toString())))
return false;
return true;
break;
case STRING:
return true;
break;
case FLOAT32:
if(!(var.toFloat()<=struc.values.at(0).toFloat()))
return false;
return true;
break;
default:
return true;
}
}
return true;
}
QVariant UAVObjectField::getMaxLimit(quint32 index)
QVariant UAVObjectField::getMaxLimit(quint32 index,int board)
{
if(!elementLimits.keys().contains(index))
return QVariant();
LimitStruct struc=elementLimits.value(index);
switch(struc.type)
foreach(LimitStruct struc,elementLimits.value(index))
{
case EQUAL:
case NOT_EQUAL:
case BIGGER:
return QVariant();
break;
break;
case BETWEEN:
return struc.values.at(1);
break;
case SMALLER:
return struc.values.at(0);
break;
default:
return QVariant();
break;
if((struc.board!=board) && board!=0 && struc.board!=0)
continue;
switch(struc.type)
{
case EQUAL:
case NOT_EQUAL:
case BIGGER:
return QVariant();
break;
break;
case BETWEEN:
return struc.values.at(1);
break;
case SMALLER:
return struc.values.at(0);
break;
default:
return QVariant();
break;
}
}
return QVariant();
return QVariant();
}
QVariant UAVObjectField::getMinLimit(quint32 index)
QVariant UAVObjectField::getMinLimit(quint32 index, int board)
{
if(!elementLimits.keys().contains(index))
return QVariant();
LimitStruct struc=elementLimits.value(index);
switch(struc.type)
foreach(LimitStruct struc,elementLimits.value(index))
{
case EQUAL:
case NOT_EQUAL:
case SMALLER:
return QVariant();
break;
break;
case BETWEEN:
return struc.values.at(0);
break;
case BIGGER:
return struc.values.at(0);
break;
default:
return QVariant();
break;
if((struc.board!=board) && board!=0 && struc.board!=0)
return QVariant();
switch(struc.type)
{
case EQUAL:
case NOT_EQUAL:
case SMALLER:
return QVariant();
break;
break;
case BETWEEN:
return struc.values.at(0);
break;
case BIGGER:
return struc.values.at(0);
break;
default:
return QVariant();
break;
}
}
return QVariant();
return QVariant();
}
void UAVObjectField::initialize(quint8* data, quint32 dataOffset, UAVObject* obj)
{

View File

@ -48,6 +48,7 @@ public:
{
LimitType type;
QList<QVariant> values;
int board;
} LimitStruct;
UAVObjectField(const QString& name, const QString& units, FieldType type, quint32 numElements, const QStringList& options,const QString& limits=QString());
@ -74,9 +75,9 @@ public:
bool isText();
QString toString();
bool isWithinLimits(QVariant var, quint32 index);
QVariant getMaxLimit(quint32 index);
QVariant getMinLimit(quint32 index);
bool isWithinLimits(QVariant var, quint32 index, int board=0);
QVariant getMaxLimit(quint32 index, int board=0);
QVariant getMinLimit(quint32 index, int board=0);
signals:
void fieldUpdated(UAVObjectField* field);
@ -91,7 +92,7 @@ protected:
quint32 offset;
quint8* data;
UAVObject* obj;
QMap<quint32,LimitStruct> elementLimits;
QMap<quint32, QList<LimitStruct> > elementLimits;
void clear();
void constructorInitialize(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options, const QString &limits);
void limitsInitialize(const QString &limits);

View File

@ -247,14 +247,6 @@ FirmwareIAPObj::DataFields UAVObjectUtilManager::getFirmwareIap()
if (!firmwareIap)
return dummy;
// The code below will ask for the object update and wait for the updated to be received,
// or the timeout of the timer, set to 1 second.
QEventLoop loop;
connect(firmwareIap, SIGNAL(objectUpdated(UAVObject*)), &loop, SLOT(quit()));
QTimer::singleShot(1000, &loop, SLOT(quit())); // Create a timeout
firmwareIap->requestUpdate();
loop.exec();
return firmwareIap->getData();
}

View File

@ -37,6 +37,7 @@ ConfigTaskWidget::ConfigTaskWidget(QWidget *parent) : QWidget(parent),isConnecte
pm = ExtensionSystem::PluginManager::instance();
objManager = pm->getObject<UAVObjectManager>();
TelemetryManager* telMngr = pm->getObject<TelemetryManager>();
utilMngr = pm->getObject<UAVObjectUtilManager>();
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
connect(telMngr, SIGNAL(connected()), this, SIGNAL(autoPilotConnected()));
@ -249,9 +250,15 @@ void ConfigTaskWidget::onAutopilotDisconnect()
void ConfigTaskWidget::onAutopilotConnect()
{
if (utilMngr)
currentBoard = utilMngr->getBoardModel();//TODO REMEMBER TO ADD THIS TO FORCE CONNECTED FUNC ON CC3D_RELEASE
invalidateObjects();
dirty=false;
isConnected=true;
foreach(objectToWidget * ow,objOfInterest)
{
loadWidgetLimits(ow->widget,ow->field,ow->index,ow->isLimited,ow->scale);
}
enableControls(true);
refreshWidgetsValues();
}
@ -1072,7 +1079,7 @@ void ConfigTaskWidget::checkWidgetsLimits(QWidget * widget,UAVObjectField * fiel
{
if(!hasLimits)
return;
if(!field->isWithinLimits(value,index))
if(!field->isWithinLimits(value,index,currentBoard))
{
if(!widget->property("styleBackup").isValid())
widget->setProperty("styleBackup",widget->styleSheet());
@ -1146,7 +1153,7 @@ void ConfigTaskWidget::loadWidgetLimits(QWidget * widget,UAVObjectField * field,
{
foreach(QString str,option)
{
if(field->isWithinLimits(str,index))
if(field->isWithinLimits(str,index,currentBoard))
cb->addItem(str);
}
}
@ -1159,33 +1166,33 @@ void ConfigTaskWidget::loadWidgetLimits(QWidget * widget,UAVObjectField * field,
{
if(field->getMaxLimit(index).isValid())
{
cb->setMaximum((double)(field->getMaxLimit(index).toDouble()/scale));
cb->setMaximum((double)(field->getMaxLimit(index,currentBoard).toDouble()/scale));
}
if(field->getMinLimit(index).isValid())
if(field->getMinLimit(index,currentBoard).isValid())
{
cb->setMinimum((double)(field->getMinLimit(index).toDouble()/scale));
cb->setMinimum((double)(field->getMinLimit(index,currentBoard).toDouble()/scale));
}
}
else if(QSpinBox * cb=qobject_cast<QSpinBox *>(widget))
{
if(field->getMaxLimit(index).isValid())
if(field->getMaxLimit(index,currentBoard).isValid())
{
cb->setMaximum((int)qRound(field->getMaxLimit(index).toDouble()/scale));
cb->setMaximum((int)qRound(field->getMaxLimit(index,currentBoard).toDouble()/scale));
}
if(field->getMinLimit(index).isValid())
if(field->getMinLimit(index,currentBoard).isValid())
{
cb->setMinimum((int)qRound(field->getMinLimit(index).toDouble()/scale));
cb->setMinimum((int)qRound(field->getMinLimit(index,currentBoard).toDouble()/scale));
}
}
else if(QSlider * cb=qobject_cast<QSlider *>(widget))
{
if(field->getMaxLimit(index).isValid())
if(field->getMaxLimit(index,currentBoard).isValid())
{
cb->setMaximum((int)qRound(field->getMaxLimit(index).toDouble()/scale));
cb->setMaximum((int)qRound(field->getMaxLimit(index,currentBoard).toDouble()/scale));
}
if(field->getMinLimit(index).isValid())
if(field->getMinLimit(index,currentBoard).isValid())
{
cb->setMinimum((int)(field->getMinLimit(index).toDouble()/scale));
cb->setMinimum((int)(field->getMinLimit(index,currentBoard).toDouble()/scale));
}
}
}

View File

@ -145,12 +145,14 @@ private slots:
void defaultButtonClicked();
void reloadButtonClicked();
private:
int currentBoard;
bool isConnected;
bool allowWidgetUpdates;
QStringList objectsList;
QList <objectToWidget*> objOfInterest;
ExtensionSystem::PluginManager *pm;
UAVObjectManager *objManager;
UAVObjectUtilManager* utilMngr;
smartSaveButton *smartsave;
QMap<UAVObject *,bool> objectUpdates;
QMap<int,QList<objectToWidget*> *> defaultReloadGroups;

View File

@ -388,6 +388,11 @@ void Telemetry::processObjectQueue()
UAVObject::UpdateMode updateMode = UAVObject::GetGcsTelemetryUpdateMode(metadata);
if ( ( objInfo.event != EV_UNPACKED ) && ( ( objInfo.event != EV_UPDATED_PERIODIC ) || ( updateMode != UAVObject::UPDATEMODE_THROTTLED ) ) )
{
QMap<quint32, ObjectTransactionInfo*>::iterator itr = transMap.find(objInfo.obj->getObjID());
if ( itr != transMap.end() ) {
qDebug() << "!!!!!! Making request for an object: " << objInfo.obj->getName() << " for which a request is already in progress!!!!!!";
return;
}
UAVObject::Metadata metadata = objInfo.obj->getMetadata();
ObjectTransactionInfo *transInfo = new ObjectTransactionInfo(this);
transInfo->obj = objInfo.obj;

View File

@ -33,7 +33,7 @@ It is expected that you have the following tools installed into the listed
locations (but any other locations are fine as well):
- Python in C:\Python27
- QtSDK in C:\Qt\2010.05 or C:\QtSDK (depending on SDK version)
- QtSDK in C:\QtSDK (depending on SDK version)
- CodeSourcery G++ in %ProgramFiles%\CodeSourcery\Sourcery G++ Lite
- msysGit in %ProgramFiles%\Git
- Unicode NSIS in %ProgramFiles%\NSIS\Unicode
@ -190,8 +190,8 @@ This set of scripts uses the MSYS package included into the msysGit
distribution and MinGW make included into the QtSDK package.
The sh.cmd, shell_script.reg and this README.txt files were written
by Oleg Semyonov (os-openpilot-org@os-propo.info) for the OpenPilot
project and are licensed under CC-BY-SA terms:
by Oleg Semyonov (os@openpilot.org) for the OpenPilot project and
are licensed under CC-BY-SA terms:
http://creativecommons.org/licenses/by-sa/3.0/

View File

@ -54,12 +54,8 @@ set NOT_FOUND=
set PATH_DIRS=
call :which MSYSGIT "%ProgramFiles%\Git\bin" git.exe
rem These two lines for qt-sdk-win-opensource-2010.05.exe:
call :which QTMINGW "C:\Qt\2010.05\mingw\bin" mingw32-make.exe
call :which QTSDK "C:\Qt\2010.05\qt\bin" qmake.exe
rem These two lines for Qt_SDK_Win_offline_v1_1_1_en.exe:
rem call :which QTMINGW "C:\QtSDK\mingw\bin" mingw32-make.exe
rem call :which QTSDK "C:\QtSDK\Desktop\Qt\4.7.3\mingw\bin" qmake.exe
call :which QTMINGW "C:\QtSDK\mingw\bin" mingw32-make.exe
call :which QTSDK "C:\QtSDK\Desktop\Qt\4.8.1\mingw\bin" qmake.exe
call :which CODESOURCERY "%ProgramFiles%\CodeSourcery\Sourcery G++ Lite\bin" cs-make.exe
call :which PYTHON "C:\Python27" python.exe
call :which UNSIS "%ProgramFiles%\NSIS\Unicode" makensis.exe

View File

@ -42,7 +42,7 @@ DEB_PACKAGE_NAME := openpilot_$(VERSION_FULL)_$(DEB_PLATFORM)
linux_deb_package: deb_build gcs
@echo $@ starting
cd .. && dpkg-buildpackage -b
cd .. && dpkg-buildpackage -b -us -uc
$(V1)mv $(ROOT_DIR)/../$(DEB_PACKAGE_NAME).deb $(BUILD_DIR)
$(V1)mv $(ROOT_DIR)/../$(DEB_PACKAGE_NAME).changes $(BUILD_DIR)
$(V1)rm -rf $(DEB_BUILD_DIR)

View File

@ -38,6 +38,7 @@
!define NSIS_DATA_TREE "."
!define GCS_BUILD_TREE "..\..\build\ground\openpilotgcs"
!define UAVO_SYNTH_TREE "..\..\build\uavobject-synthetics"
!define AEROSIMRC_TREE "..\..\build\ground\AeroSIM-RC"
; Default installation folder
InstallDir "$PROGRAMFILES\OpenPilot"
@ -161,7 +162,7 @@ Section "Core files" InSecCore
SectionEnd
; Copy GCS plugins
Section "Plugins" InSecPlugins
Section "-Plugins" InSecPlugins
SectionIn RO
SetOutPath "$INSTDIR\lib\openpilotgcs\plugins"
File /r "${GCS_BUILD_TREE}\lib\openpilotgcs\plugins\*.dll"
@ -169,7 +170,7 @@ Section "Plugins" InSecPlugins
SectionEnd
; Copy GCS resources
Section "Resources" InSecResources
Section "-Resources" InSecResources
SetOutPath "$INSTDIR\share\openpilotgcs\diagrams"
File /r "${GCS_BUILD_TREE}\share\openpilotgcs\diagrams\*"
SetOutPath "$INSTDIR\share\openpilotgcs\dials"
@ -183,14 +184,14 @@ Section "Resources" InSecResources
SectionEnd
; Copy Notify plugin sound files
Section "Sound files" InSecSounds
Section "-Sound files" InSecSounds
SetOutPath "$INSTDIR\share\openpilotgcs\sounds"
File /r "${GCS_BUILD_TREE}\share\openpilotgcs\sounds\*"
SectionEnd
; Copy localization files
; Disabled until GCS source is stable and properly localized
Section "Localization" InSecLocalization
Section "-Localization" InSecLocalization
SetOutPath "$INSTDIR\share\openpilotgcs\translations"
; File /r "${GCS_BUILD_TREE}\share\openpilotgcs\translations\openpilotgcs_*.qm"
File /r "${GCS_BUILD_TREE}\share\openpilotgcs\translations\qt_*.qm"
@ -229,6 +230,12 @@ Section "CDC driver" InSecInstallDrivers
ExecWait '"$PLUGINSDIR\dpinst.exe" /lm /path "$INSTDIR\drivers"'
SectionEnd
; AeroSimRC plugin files
Section "AeroSimRC plugin" InSecAeroSimRC
SetOutPath "$INSTDIR\misc\AeroSIM-RC"
File /r "${AEROSIMRC_TREE}\*"
SectionEnd
Section "Shortcuts" InSecShortcuts
; Create desktop and start menu shortcuts
SetOutPath "$INSTDIR"
@ -277,6 +284,7 @@ SectionEnd
!insertmacro MUI_DESCRIPTION_TEXT ${InSecUtilities} $(DESC_InSecUtilities)
!insertmacro MUI_DESCRIPTION_TEXT ${InSecDrivers} $(DESC_InSecDrivers)
!insertmacro MUI_DESCRIPTION_TEXT ${InSecInstallDrivers} $(DESC_InSecInstallDrivers)
!insertmacro MUI_DESCRIPTION_TEXT ${InSecAeroSimRC} $(DESC_InSecAeroSimRC)
!insertmacro MUI_DESCRIPTION_TEXT ${InSecShortcuts} $(DESC_InSecShortcuts)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
@ -301,6 +309,7 @@ Section "un.OpenPilot GCS" UnSecProgram
RMDir /r /rebootok "$INSTDIR\firmware"
RMDir /r /rebootok "$INSTDIR\utilities"
RMDir /r /rebootok "$INSTDIR\drivers"
RMDir /r /rebootok "$INSTDIR\misc"
Delete /rebootok "$INSTDIR\HISTORY.txt"
Delete /rebootok "$INSTDIR\Uninstall.exe"

View File

@ -33,7 +33,8 @@
LangString DESC_InSecFirmware ${LANG_GERMAN} "OpenPilot firmware binaries."
LangString DESC_InSecUtilities ${LANG_GERMAN} "OpenPilot Dienstprogramme (Matlab Log Parser)."
LangString DESC_InSecDrivers ${LANG_GERMAN} "OpenPilot Hardware Treiberdateien (optionaler OpenPilot CDC Treiber)."
LangString DESC_InSecInstallDrivers ${LANG_GERMAN} "Installiere OpenPilot CDC Treiber (optional)."
LangString DESC_InSecInstallDrivers ${LANG_GERMAN} "OpenPilot CDC Treiber (optional)."
LangString DESC_InSecAeroSimRC ${LANG_GERMAN} "AeroSimRC plugin files with sample configuration."
LangString DESC_InSecShortcuts ${LANG_GERMAN} "Installiere Verknüpfungen unter Startmenü->Anwendungen."
;--------------------------------

View File

@ -33,7 +33,8 @@
LangString DESC_InSecFirmware ${LANG_ENGLISH} "OpenPilot firmware binaries."
LangString DESC_InSecUtilities ${LANG_ENGLISH} "OpenPilot utilities (Matlab log parser)."
LangString DESC_InSecDrivers ${LANG_ENGLISH} "OpenPilot hardware driver files (optional OpenPilot CDC driver)."
LangString DESC_InSecInstallDrivers ${LANG_ENGLISH} "Install OpenPilot CDC driver (optional)."
LangString DESC_InSecInstallDrivers ${LANG_ENGLISH} "Optional OpenPilot CDC driver (virtual USB COM port)."
LangString DESC_InSecAeroSimRC ${LANG_ENGLISH} "AeroSimRC plugin files with sample configuration."
LangString DESC_InSecShortcuts ${LANG_ENGLISH} "Install application start menu shortcuts."
;--------------------------------

View File

@ -33,7 +33,8 @@
LangString DESC_InSecFirmware ${LANG_SPANISH} "OpenPilot firmware binaries."
LangString DESC_InSecUtilities ${LANG_SPANISH} "OpenPilot utilities (Matlab log parser)."
LangString DESC_InSecDrivers ${LANG_SPANISH} "OpenPilot hardware driver files (optional OpenPilot CDC driver)."
LangString DESC_InSecInstallDrivers ${LANG_SPANISH} "Install OpenPilot CDC driver (optional)."
LangString DESC_InSecInstallDrivers ${LANG_SPANISH} "Optional OpenPilot CDC driver (virtual USB COM port)."
LangString DESC_InSecAeroSimRC ${LANG_SPANISH} "AeroSimRC plugin files with sample configuration."
LangString DESC_InSecShortcuts ${LANG_SPANISH} "Instalar accesos directos de la aplicación (menú inicio y escritorio)."
;--------------------------------

View File

@ -33,7 +33,8 @@
LangString DESC_InSecFirmware ${LANG_FRENCH} "OpenPilot firmware binaries."
LangString DESC_InSecUtilities ${LANG_FRENCH} "OpenPilot utilities (Matlab log parser)."
LangString DESC_InSecDrivers ${LANG_FRENCH} "OpenPilot hardware driver files (optional OpenPilot CDC driver)."
LangString DESC_InSecInstallDrivers ${LANG_FRENCH} "Install OpenPilot CDC driver (optional)."
LangString DESC_InSecInstallDrivers ${LANG_FRENCH} "Optional OpenPilot CDC driver (virtual USB COM port)."
LangString DESC_InSecAeroSimRC ${LANG_FRENCH} "AeroSimRC plugin files with sample configuration."
LangString DESC_InSecShortcuts ${LANG_FRENCH} "Installer les raccourcis dans le menu démarrer."
;--------------------------------

View File

@ -33,7 +33,8 @@
LangString DESC_InSecFirmware ${LANG_RUSSIAN} "Файлы прошивок OpenPilot."
LangString DESC_InSecUtilities ${LANG_RUSSIAN} "Утилиты (конвертор логов для Matlab)."
LangString DESC_InSecDrivers ${LANG_RUSSIAN} "Файлы драйверов (опциональный драйвер CDC порта)."
LangString DESC_InSecInstallDrivers ${LANG_RUSSIAN} "Установка опционального OpenPilot CDC драйвера."
LangString DESC_InSecInstallDrivers ${LANG_RUSSIAN} "Опциональный OpenPilot CDC драйвер (виртуальный USB COM порт)."
LangString DESC_InSecAeroSimRC ${LANG_RUSSIAN} "Файлы плагина для симулятора AeroSimRC с примером конфигурации."
LangString DESC_InSecShortcuts ${LANG_RUSSIAN} "Установка ярлыков для приложения."
;--------------------------------

View File

@ -33,7 +33,8 @@
LangString DESC_InSecFirmware ${LANG_TRADCHINESE} "OpenPilot firmware binaries."
LangString DESC_InSecUtilities ${LANG_TRADCHINESE} "OpenPilot utilities (Matlab log parser)."
LangString DESC_InSecDrivers ${LANG_TRADCHINESE} "OpenPilot hardware driver files (optional OpenPilot CDC driver)."
LangString DESC_InSecInstallDrivers ${LANG_TRADCHINESE} "Install OpenPilot CDC driver (optional)."
LangString DESC_InSecInstallDrivers ${LANG_TRADCHINESE} "Optional OpenPilot CDC driver (virtual USB COM port)."
LangString DESC_InSecAeroSimRC ${LANG_TRADCHINESE} "AeroSimRC plugin files with sample configuration."
LangString DESC_InSecShortcuts ${LANG_TRADCHINESE} "安装开始菜单的快捷方式."
;--------------------------------

View File

@ -10,7 +10,7 @@
<field name="crc" units="" type="uint32" elements="1"/>
<access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="true" updatemode="manual" period="0"/>
<telemetryflight acked="true" updatemode="manual" period="0"/>
<telemetryflight acked="true" updatemode="onchange" period="0"/>
<logging updatemode="manual" period="0"/>
</object>
</xml>

View File

@ -25,6 +25,7 @@
<!-- Note these options values should be identical to those defined in FlightMode -->
<field name="FlightModePosition" units="" type="enum" elements="3" options="Manual,Stabilized1,Stabilized2,Stabilized3,AltitudeHold,VelocityControl,PositionHold,PathPlanner,RTH,Land" defaultvalue="Manual,Stabilized1,Stabilized2"/>
<field name="FlightModeNumber" units="" type="uint8" elements="1" defaultvalue="3"/>
<field name="FlightModePosition" units="" type="enum" elements="6" options="Manual,Stabilized1,Stabilized2,Stabilized3,AltitudeHold,VelocityControl,PositionHold,PathPlanner,RTH,Land" defaultvalue="Manual,Stabilized1,Stabilized2,Stabilized3,Stabilized1,Stabilized2" limits="%0401NE:AltitudeHold:VelocityControl:PositionHold;%0402NE:AltitudeHold:VelocityControl:PositionHold,%0401NE:AltitudeHold:VelocityControl:PositionHold;%0402NE:AltitudeHold:VelocityControl:PositionHold,%0401NE:AltitudeHold:VelocityControl:PositionHold;%0402NE:AltitudeHold:VelocityControl:PositionHold,%0401NE:AltitudeHold:VelocityControl:PositionHold;%0402NE:AltitudeHold:VelocityControl:PositionHold,%0401NE:AltitudeHold:VelocityControl:PositionHold;%0402NE:AltitudeHold:VelocityControl:PositionHold,%0401NE:AltitudeHold:VelocityControl:PositionHold;%0402NE:AltitudeHold:VelocityControl:PositionHold"/>
<field name="ArmedTimeout" units="ms" type="uint16" elements="1" defaultvalue="30000"/>
<field name="FailsafeBehavior" units="" type="enum" elements="1" options="None,RTH" defaultvalue="None"/>