mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
Merge remote-tracking branch 'op-public/next' into revo-next
Conflicts: shared/uavobjectdefinition/manualcontrolsettings.xml shared/uavobjectdefinition/taskinfo.xml
This commit is contained in:
commit
1f1b240b2a
@ -1,5 +1,9 @@
|
||||
Short summary of changes. For a complete list see the git log.
|
||||
|
||||
2012-08-11
|
||||
CopterControl can now emulate an 8-channel USB HID joystick. Primarily,
|
||||
this lets you use any RC transmitter with flight simulators on your PC.
|
||||
|
||||
2012-07-20
|
||||
AeroSimRC simulator plugin is now included into the Windows distribution
|
||||
(will be installed into .../OpenPilot/misc/AeroSIM-RC directory). Still
|
||||
|
@ -239,6 +239,7 @@ SRC += $(PIOSSTM32F10X)/pios_bl_helper.c
|
||||
SRC += $(PIOSSTM32F10X)/pios_usb.c
|
||||
SRC += $(PIOSSTM32F10X)/pios_usbhook.c
|
||||
SRC += $(PIOSSTM32F10X)/pios_usb_hid.c
|
||||
SRC += $(PIOSSTM32F10X)/pios_usb_rctx.c
|
||||
SRC += $(PIOSSTM32F10X)/pios_usb_cdc.c
|
||||
SRC += $(PIOSSTM32F10X)/pios_usb_hid_istr.c
|
||||
SRC += $(PIOSSTM32F10X)/pios_usb_hid_pwr.c
|
||||
@ -502,6 +503,7 @@ endif
|
||||
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Werror
|
||||
CFLAGS += -ffunction-sections -fdata-sections
|
||||
CFLAGS += -Wa,-adhlns=$(addprefix $(OUTDIR)/, $(notdir $(addsuffix .lst, $(basename $<))))
|
||||
# Compiler flags to generate dependency files:
|
||||
CFLAGS += -MD -MP -MF $(OUTDIR)/dep/$(@F).d
|
||||
|
@ -66,6 +66,7 @@
|
||||
#define PIOS_INCLUDE_USART
|
||||
#define PIOS_INCLUDE_USB
|
||||
#define PIOS_INCLUDE_USB_HID
|
||||
#define PIOS_INCLUDE_USB_RCTX
|
||||
#define PIOS_INCLUDE_USB_CDC
|
||||
#define PIOS_INCLUDE_COM
|
||||
#define PIOS_INCLUDE_SETTINGS
|
||||
@ -94,8 +95,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
|
||||
|
@ -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
|
||||
|
@ -67,6 +67,8 @@ uint32_t pios_com_vcp_id;
|
||||
uint32_t pios_com_gps_id;
|
||||
uint32_t pios_com_bridge_id;
|
||||
|
||||
uint32_t pios_usb_rctx_id;
|
||||
|
||||
/**
|
||||
* Configuration for MPU6000 chip
|
||||
*/
|
||||
@ -358,6 +360,15 @@ void PIOS_Board_Init(void) {
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
break;
|
||||
case HWSETTINGS_USB_HIDPORT_RCTRANSMITTER:
|
||||
#if defined(PIOS_INCLUDE_USB_RCTX)
|
||||
{
|
||||
if (PIOS_USB_RCTX_Init(&pios_usb_rctx_id, &pios_usb_rctx_cfg, pios_usb_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_USB_RCTX */
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
|
@ -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)
|
||||
|
@ -65,24 +65,25 @@ static xQueueHandle queue;
|
||||
static xTaskHandle taskHandle;
|
||||
|
||||
static float lastResult[MAX_MIX_ACTUATORS]={0,0,0,0,0,0,0,0};
|
||||
static float lastFilteredResult[MAX_MIX_ACTUATORS]={0,0,0,0,0,0,0,0};
|
||||
static float filterAccumulator[MAX_MIX_ACTUATORS]={0,0,0,0,0,0,0,0};
|
||||
// used to inform the actuator thread that actuator update rate is changed
|
||||
static uint8_t updateRateChanged = 0;
|
||||
static volatile bool actuator_settings_updated;
|
||||
// used to inform the actuator thread that mixer settings are changed
|
||||
static volatile bool mixer_settings_updated;
|
||||
|
||||
// Private functions
|
||||
static void actuatorTask(void* parameters);
|
||||
static void actuator_update_rate(UAVObjEvent *);
|
||||
static int16_t scaleChannel(float value, int16_t max, int16_t min, int16_t neutral);
|
||||
static void setFailsafe();
|
||||
static void setFailsafe(const ActuatorSettingsData * actuatorSettings, const MixerSettingsData * mixerSettings);
|
||||
static float MixerCurve(const float throttle, const float* curve, uint8_t elements);
|
||||
static bool set_channel(uint8_t mixer_channel, uint16_t value);
|
||||
static void change_update_rate();
|
||||
static bool set_channel(uint8_t mixer_channel, uint16_t value, const ActuatorSettingsData * actuatorSettings);
|
||||
static void actuator_update_rate_if_changed(const ActuatorSettingsData * actuatorSettings, bool force_update);
|
||||
static void MixerSettingsUpdatedCb(UAVObjEvent * ev);
|
||||
static void ActuatorSettingsUpdatedCb(UAVObjEvent * ev);
|
||||
float ProcessMixer(const int index, const float curve1, const float curve2,
|
||||
MixerSettingsData* mixerSettings, ActuatorDesiredData* desired,
|
||||
const MixerSettingsData* mixerSettings, ActuatorDesiredData* desired,
|
||||
const float period);
|
||||
|
||||
static uint16_t lastChannelUpdateFreq[ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM] = {0,0,0,0};
|
||||
//this structure is equivalent to the UAVObjects for one mixer.
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
@ -109,22 +110,26 @@ int32_t ActuatorStart()
|
||||
*/
|
||||
int32_t ActuatorInitialize()
|
||||
{
|
||||
// Create object queue
|
||||
queue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(UAVObjEvent));
|
||||
|
||||
// Register for notification of changes to ActuatorSettings
|
||||
ActuatorSettingsInitialize();
|
||||
ActuatorDesiredInitialize();
|
||||
MixerSettingsInitialize();
|
||||
ActuatorCommandInitialize();
|
||||
#if defined(DIAGNOSTICS)
|
||||
MixerStatusInitialize();
|
||||
#endif
|
||||
ActuatorSettingsConnectCallback(ActuatorSettingsUpdatedCb);
|
||||
|
||||
// Listen for ExampleObject1 updates
|
||||
// Register for notification of changes to MixerSettings
|
||||
MixerSettingsInitialize();
|
||||
MixerSettingsConnectCallback(MixerSettingsUpdatedCb);
|
||||
|
||||
// Listen for ActuatorDesired updates (Primary input to this module)
|
||||
ActuatorDesiredInitialize();
|
||||
queue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(UAVObjEvent));
|
||||
ActuatorDesiredConnectQueue(queue);
|
||||
|
||||
// If settings change, update the output rate
|
||||
ActuatorSettingsConnectCallback(actuator_update_rate);
|
||||
// Primary output of this module
|
||||
ActuatorCommandInitialize();
|
||||
|
||||
#if defined(DIAGNOSTICS)
|
||||
// UAVO only used for inspecting the internal status of the mixer during debug
|
||||
MixerStatusInitialize();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -151,22 +156,25 @@ static void actuatorTask(void* parameters)
|
||||
float dT = 0.0f;
|
||||
|
||||
ActuatorCommandData command;
|
||||
MixerSettingsData mixerSettings;
|
||||
ActuatorDesiredData desired;
|
||||
MixerStatusData mixerStatus;
|
||||
FlightStatusData flightStatus;
|
||||
|
||||
uint8_t MotorsSpinWhileArmed;
|
||||
int16_t ChannelMax[ACTUATORCOMMAND_CHANNEL_NUMELEM];
|
||||
int16_t ChannelMin[ACTUATORCOMMAND_CHANNEL_NUMELEM];
|
||||
int16_t ChannelNeutral[ACTUATORCOMMAND_CHANNEL_NUMELEM];
|
||||
/* Read initial values of ActuatorSettings */
|
||||
ActuatorSettingsData actuatorSettings;
|
||||
actuator_settings_updated = false;
|
||||
ActuatorSettingsGet(&actuatorSettings);
|
||||
|
||||
change_update_rate();
|
||||
/* Read initial values of MixerSettings */
|
||||
MixerSettingsData mixerSettings;
|
||||
mixer_settings_updated = false;
|
||||
MixerSettingsGet(&mixerSettings);
|
||||
|
||||
float * status = (float *)&mixerStatus; //access status objects as an array of floats
|
||||
/* Force an initial configuration of the actuator update rates */
|
||||
actuator_update_rate_if_changed(&actuatorSettings, true);
|
||||
|
||||
// Go to the neutral (failsafe) values until an ActuatorDesired update is received
|
||||
setFailsafe();
|
||||
setFailsafe(&actuatorSettings, &mixerSettings);
|
||||
|
||||
// Main task loop
|
||||
lastSysTime = xTaskGetTickCount();
|
||||
@ -174,17 +182,24 @@ static void actuatorTask(void* parameters)
|
||||
{
|
||||
PIOS_WDG_UpdateFlag(PIOS_WDG_ACTUATOR);
|
||||
|
||||
// Wait until the ActuatorDesired object is updated, if a timeout then go to failsafe
|
||||
if ( xQueueReceive(queue, &ev, FAILSAFE_TIMEOUT_MS / portTICK_RATE_MS) != pdTRUE )
|
||||
{
|
||||
setFailsafe();
|
||||
continue;
|
||||
// Wait until the ActuatorDesired object is updated
|
||||
uint8_t rc = xQueueReceive(queue, &ev, FAILSAFE_TIMEOUT_MS / portTICK_RATE_MS);
|
||||
|
||||
/* Process settings updated events even in timeout case so we always act on the latest settings */
|
||||
if (actuator_settings_updated) {
|
||||
actuator_settings_updated = false;
|
||||
ActuatorSettingsGet (&actuatorSettings);
|
||||
actuator_update_rate_if_changed (&actuatorSettings, false);
|
||||
}
|
||||
if (mixer_settings_updated) {
|
||||
mixer_settings_updated = false;
|
||||
MixerSettingsGet (&mixerSettings);
|
||||
}
|
||||
|
||||
if(updateRateChanged!=0)
|
||||
{
|
||||
change_update_rate();
|
||||
updateRateChanged=0;
|
||||
if (rc != pdTRUE) {
|
||||
/* Update of ActuatorDesired timed out. Go to failsafe */
|
||||
setFailsafe(&actuatorSettings, &mixerSettings);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check how long since last update
|
||||
@ -194,18 +209,12 @@ static void actuatorTask(void* parameters)
|
||||
lastSysTime = thisSysTime;
|
||||
|
||||
FlightStatusGet(&flightStatus);
|
||||
MixerSettingsGet (&mixerSettings);
|
||||
ActuatorDesiredGet(&desired);
|
||||
ActuatorCommandGet(&command);
|
||||
|
||||
#if defined(DIAGNOSTICS)
|
||||
MixerStatusGet(&mixerStatus);
|
||||
#endif
|
||||
ActuatorSettingsMotorsSpinWhileArmedGet(&MotorsSpinWhileArmed);
|
||||
ActuatorSettingsChannelMaxGet(ChannelMax);
|
||||
ActuatorSettingsChannelMinGet(ChannelMin);
|
||||
ActuatorSettingsChannelNeutralGet(ChannelNeutral);
|
||||
|
||||
int nMixers = 0;
|
||||
Mixer_t * mixers = (Mixer_t *)&mixerSettings.Mixer1Type;
|
||||
for(int ct=0; ct < MAX_MIX_ACTUATORS; ct++)
|
||||
@ -217,7 +226,7 @@ static void actuatorTask(void* parameters)
|
||||
}
|
||||
if((nMixers < 2) && !ActuatorCommandReadOnly()) //Nothing can fly with less than two mixers.
|
||||
{
|
||||
setFailsafe(); // So that channels like PWM buzzer keep working
|
||||
setFailsafe(&actuatorSettings, &mixerSettings); // So that channels like PWM buzzer keep working
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -225,7 +234,7 @@ static void actuatorTask(void* parameters)
|
||||
|
||||
bool armed = flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED;
|
||||
bool positiveThrottle = desired.Throttle >= 0.00f;
|
||||
bool spinWhileArmed = MotorsSpinWhileArmed == ACTUATORSETTINGS_MOTORSSPINWHILEARMED_TRUE;
|
||||
bool spinWhileArmed = actuatorSettings.MotorsSpinWhileArmed == ACTUATORSETTINGS_MOTORSSPINWHILEARMED_TRUE;
|
||||
|
||||
float curve1 = MixerCurve(desired.Throttle,mixerSettings.ThrottleCurve1,MIXERSETTINGS_THROTTLECURVE1_NUMELEM);
|
||||
|
||||
@ -264,6 +273,8 @@ static void actuatorTask(void* parameters)
|
||||
break;
|
||||
}
|
||||
|
||||
float * status = (float *)&mixerStatus; //access status objects as an array of floats
|
||||
|
||||
for(int ct=0; ct < MAX_MIX_ACTUATORS; ct++)
|
||||
{
|
||||
if(mixers[ct].type == MIXERSETTINGS_MIXER1TYPE_DISABLED) {
|
||||
@ -337,9 +348,9 @@ static void actuatorTask(void* parameters)
|
||||
|
||||
for(int i = 0; i < MAX_MIX_ACTUATORS; i++)
|
||||
command.Channel[i] = scaleChannel(status[i],
|
||||
ChannelMax[i],
|
||||
ChannelMin[i],
|
||||
ChannelNeutral[i]);
|
||||
actuatorSettings.ChannelMax[i],
|
||||
actuatorSettings.ChannelMin[i],
|
||||
actuatorSettings.ChannelNeutral[i]);
|
||||
|
||||
// Store update time
|
||||
command.UpdateTime = 1000.0f*dT;
|
||||
@ -361,7 +372,7 @@ static void actuatorTask(void* parameters)
|
||||
|
||||
for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n)
|
||||
{
|
||||
success &= set_channel(n, command.Channel[n]);
|
||||
success &= set_channel(n, command.Channel[n], &actuatorSettings);
|
||||
}
|
||||
|
||||
if(!success) {
|
||||
@ -379,15 +390,18 @@ static void actuatorTask(void* parameters)
|
||||
*Process mixing for one actuator
|
||||
*/
|
||||
float ProcessMixer(const int index, const float curve1, const float curve2,
|
||||
MixerSettingsData* mixerSettings, ActuatorDesiredData* desired, const float period)
|
||||
const MixerSettingsData* mixerSettings, ActuatorDesiredData* desired, const float period)
|
||||
{
|
||||
Mixer_t * mixers = (Mixer_t *)&mixerSettings->Mixer1Type; //pointer to array of mixers in UAVObjects
|
||||
Mixer_t * mixer = &mixers[index];
|
||||
static float lastFilteredResult[MAX_MIX_ACTUATORS];
|
||||
const Mixer_t * mixers = (Mixer_t *)&mixerSettings->Mixer1Type; //pointer to array of mixers in UAVObjects
|
||||
const Mixer_t * mixer = &mixers[index];
|
||||
|
||||
float result = (((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_THROTTLECURVE1] / 128.0f) * curve1) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_THROTTLECURVE2] / 128.0f) * curve2) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_ROLL] / 128.0f) * desired->Roll) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_PITCH] / 128.0f) * desired->Pitch) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_YAW] / 128.0f) * desired->Yaw);
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_THROTTLECURVE2] / 128.0f) * curve2) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_ROLL] / 128.0f) * desired->Roll) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_PITCH] / 128.0f) * desired->Pitch) +
|
||||
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_YAW] / 128.0f) * desired->Yaw);
|
||||
|
||||
if(mixer->type == MIXERSETTINGS_MIXER1TYPE_MOTOR)
|
||||
{
|
||||
if(result < 0.0f) //idle throttle
|
||||
@ -501,19 +515,13 @@ static int16_t scaleChannel(float value, int16_t max, int16_t min, int16_t neutr
|
||||
/**
|
||||
* Set actuator output to the neutral values (failsafe)
|
||||
*/
|
||||
static void setFailsafe()
|
||||
static void setFailsafe(const ActuatorSettingsData * actuatorSettings, const MixerSettingsData * mixerSettings)
|
||||
{
|
||||
/* grab only the modules parts that we are going to use */
|
||||
int16_t ChannelMin[ACTUATORCOMMAND_CHANNEL_NUMELEM];
|
||||
ActuatorSettingsChannelMinGet(ChannelMin);
|
||||
int16_t ChannelNeutral[ACTUATORCOMMAND_CHANNEL_NUMELEM];
|
||||
ActuatorSettingsChannelNeutralGet(ChannelNeutral);
|
||||
/* grab only the parts that we are going to use */
|
||||
int16_t Channel[ACTUATORCOMMAND_CHANNEL_NUMELEM];
|
||||
ActuatorCommandChannelGet(Channel);
|
||||
|
||||
MixerSettingsData mixerSettings;
|
||||
MixerSettingsGet (&mixerSettings);
|
||||
Mixer_t * mixers = (Mixer_t *)&mixerSettings.Mixer1Type; //pointer to array of mixers in UAVObjects
|
||||
const Mixer_t * mixers = (Mixer_t *)&mixerSettings->Mixer1Type; //pointer to array of mixers in UAVObjects
|
||||
|
||||
// Reset ActuatorCommand to safe values
|
||||
for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n)
|
||||
@ -521,11 +529,11 @@ static void setFailsafe()
|
||||
|
||||
if(mixers[n].type == MIXERSETTINGS_MIXER1TYPE_MOTOR)
|
||||
{
|
||||
Channel[n] = ChannelMin[n];
|
||||
Channel[n] = actuatorSettings->ChannelMin[n];
|
||||
}
|
||||
else if(mixers[n].type == MIXERSETTINGS_MIXER1TYPE_SERVO)
|
||||
{
|
||||
Channel[n] = ChannelNeutral[n];
|
||||
Channel[n] = actuatorSettings->ChannelNeutral[n];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -541,54 +549,22 @@ static void setFailsafe()
|
||||
// Update servo outputs
|
||||
for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n)
|
||||
{
|
||||
set_channel(n, Channel[n]);
|
||||
set_channel(n, Channel[n], actuatorSettings);
|
||||
}
|
||||
|
||||
// Update output object's parts that we changed
|
||||
ActuatorCommandChannelSet(Channel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Update the servo update rate
|
||||
*/
|
||||
static void actuator_update_rate(UAVObjEvent * ev)
|
||||
{
|
||||
uint16_t ChannelUpdateFreq[ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM];
|
||||
// ActuatoSettings are not changed
|
||||
if ( ev->obj != ActuatorSettingsHandle() )
|
||||
return;
|
||||
|
||||
ActuatorSettingsChannelUpdateFreqGet(ChannelUpdateFreq);
|
||||
// check if the any rate setting is changed
|
||||
if (lastChannelUpdateFreq[0]!=0 && memcmp(&lastChannelUpdateFreq[0], &ChannelUpdateFreq[0], sizeof(int16_t) * ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM) ==0)
|
||||
return;
|
||||
// signal to the actuator task that ChannelUpdateFreq are changed
|
||||
updateRateChanged = 1;
|
||||
}
|
||||
/**
|
||||
* @brief Change the update rates according to the ActuatorSettingsChannelUpdateFreq.
|
||||
*/
|
||||
static void change_update_rate()
|
||||
{
|
||||
uint16_t ChannelUpdateFreq[ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM];
|
||||
// save the new rates
|
||||
ActuatorSettingsChannelUpdateFreqGet(ChannelUpdateFreq);
|
||||
memcpy(lastChannelUpdateFreq, ChannelUpdateFreq, sizeof(int16_t) * ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM);
|
||||
PIOS_Servo_SetHz(&ChannelUpdateFreq[0], ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM);
|
||||
}
|
||||
|
||||
#if defined(ARCH_POSIX) || defined(ARCH_WIN32)
|
||||
static bool set_channel(uint8_t mixer_channel, uint16_t value) {
|
||||
static bool set_channel(uint8_t mixer_channel, uint16_t value, const ActuatorSettingsData * actuatorSettings)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static bool set_channel(uint8_t mixer_channel, uint16_t value) {
|
||||
|
||||
ActuatorSettingsData settings;
|
||||
ActuatorSettingsGet(&settings);
|
||||
|
||||
switch(settings.ChannelType[mixer_channel]) {
|
||||
static bool set_channel(uint8_t mixer_channel, uint16_t value, const ActuatorSettingsData * actuatorSettings)
|
||||
{
|
||||
switch(actuatorSettings->ChannelType[mixer_channel]) {
|
||||
case ACTUATORSETTINGS_CHANNELTYPE_PWMALARMBUZZER: {
|
||||
// This is for buzzers that take a PWM input
|
||||
|
||||
@ -631,18 +607,18 @@ static bool set_channel(uint8_t mixer_channel, uint16_t value) {
|
||||
lastSysTime = thisSysTime;
|
||||
}
|
||||
}
|
||||
PIOS_Servo_Set( settings.ChannelAddr[mixer_channel],
|
||||
buzzOn?settings.ChannelMax[mixer_channel]:settings.ChannelMin[mixer_channel]);
|
||||
PIOS_Servo_Set(actuatorSettings->ChannelAddr[mixer_channel],
|
||||
buzzOn?actuatorSettings->ChannelMax[mixer_channel]:actuatorSettings->ChannelMin[mixer_channel]);
|
||||
return true;
|
||||
}
|
||||
case ACTUATORSETTINGS_CHANNELTYPE_PWM:
|
||||
PIOS_Servo_Set(settings.ChannelAddr[mixer_channel], value);
|
||||
PIOS_Servo_Set(actuatorSettings->ChannelAddr[mixer_channel], value);
|
||||
return true;
|
||||
#if defined(PIOS_INCLUDE_I2C_ESC)
|
||||
case ACTUATORSETTINGS_CHANNELTYPE_MK:
|
||||
return PIOS_SetMKSpeed(settings.ChannelAddr[mixer_channel],value);
|
||||
return PIOS_SetMKSpeed(actuatorSettings->ChannelAddr[mixer_channel],value);
|
||||
case ACTUATORSETTINGS_CHANNELTYPE_ASTEC4:
|
||||
return PIOS_SetAstec4Speed(settings.ChannelAddr[mixer_channel],value);
|
||||
return PIOS_SetAstec4Speed(actuatorSettings->ChannelAddr[mixer_channel],value);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@ -654,6 +630,35 @@ static bool set_channel(uint8_t mixer_channel, uint16_t value) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Update the servo update rate
|
||||
*/
|
||||
static void actuator_update_rate_if_changed(const ActuatorSettingsData * actuatorSettings, bool force_update)
|
||||
{
|
||||
static uint16_t prevChannelUpdateFreq[ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM];
|
||||
|
||||
// check if the any rate setting is changed
|
||||
if (force_update ||
|
||||
memcmp (prevChannelUpdateFreq,
|
||||
actuatorSettings->ChannelUpdateFreq,
|
||||
sizeof(prevChannelUpdateFreq)) != 0) {
|
||||
/* Something has changed, apply the settings to HW */
|
||||
memcpy (prevChannelUpdateFreq,
|
||||
actuatorSettings->ChannelUpdateFreq,
|
||||
sizeof(prevChannelUpdateFreq));
|
||||
PIOS_Servo_SetHz(actuatorSettings->ChannelUpdateFreq, ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM);
|
||||
}
|
||||
}
|
||||
|
||||
static void ActuatorSettingsUpdatedCb(UAVObjEvent * ev)
|
||||
{
|
||||
actuator_settings_updated = true;
|
||||
}
|
||||
|
||||
static void MixerSettingsUpdatedCb(UAVObjEvent * ev)
|
||||
{
|
||||
mixer_settings_updated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
@ -66,7 +66,7 @@ static float GravityAccel(float latitude, float longitude, float altitude);
|
||||
|
||||
#ifdef PIOS_GPS_SETS_HOMELOCATION
|
||||
// Unfortunately need a good size stack for the WMM calculation
|
||||
#define STACK_SIZE_BYTES 750
|
||||
#define STACK_SIZE_BYTES 784
|
||||
#else
|
||||
#if defined(PIOS_GPS_MINIMAL)
|
||||
#define STACK_SIZE_BYTES 500
|
||||
|
@ -49,6 +49,10 @@
|
||||
#include "stabilizationdesired.h"
|
||||
#include "receiveractivity.h"
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_RCTX)
|
||||
#include "pios_usb_rctx.h"
|
||||
#endif /* PIOS_INCLUDE_USB_RCTX */
|
||||
|
||||
// Private constants
|
||||
#if defined(PIOS_MANUAL_STACK_SIZE)
|
||||
#define STACK_SIZE_BYTES PIOS_MANUAL_STACK_SIZE
|
||||
@ -371,6 +375,15 @@ static void manualControlTask(void *parameters)
|
||||
|
||||
// Update cmd object
|
||||
ManualControlCommandSet(&cmd);
|
||||
#if defined(PIOS_INCLUDE_USB_RCTX)
|
||||
if (pios_usb_rctx_id) {
|
||||
PIOS_USB_RCTX_Update(pios_usb_rctx_id,
|
||||
cmd.Channel,
|
||||
settings.ChannelMin,
|
||||
settings.ChannelMax,
|
||||
NELEMENTS(cmd.Channel));
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_USB_RCTX */
|
||||
|
||||
} else {
|
||||
ManualControlCommandGet(&cmd); /* Under GCS control */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -458,15 +463,6 @@ static void updateSystemAlarms()
|
||||
AlarmsClear(SYSTEMALARMS_ALARM_STACKOVERFLOW);
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_SDCARD)
|
||||
// Check for SD card
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_SDCARD, SYSTEMALARMS_ALARM_ERROR);
|
||||
} else {
|
||||
AlarmsClear(SYSTEMALARMS_ALARM_SDCARD);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check for event errors
|
||||
UAVObjGetStats(&objStats);
|
||||
EventGetStats(&evStats);
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
/* Public Functions */
|
||||
extern void PIOS_Servo_Init(void);
|
||||
extern void PIOS_Servo_SetHz(uint16_t * speeds, uint8_t num_banks);
|
||||
extern void PIOS_Servo_SetHz(const uint16_t * speeds, uint8_t num_banks);
|
||||
extern void PIOS_Servo_Set(uint8_t Servo, uint16_t Position);
|
||||
|
||||
#endif /* PIOS_SERVO_H */
|
||||
|
@ -50,7 +50,7 @@ void PIOS_Servo_Init(void)
|
||||
* \param[in] onetofour Rate for outputs 1 to 4 (Hz)
|
||||
* \param[in] fivetoeight Rate for outputs 5 to 8 (Hz)
|
||||
*/
|
||||
void PIOS_Servo_SetHz(uint16_t * banks, uint8_t num_banks)
|
||||
void PIOS_Servo_SetHz(const uint16_t * banks, uint8_t num_banks)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ void PIOS_Servo_Init(void)
|
||||
* \param[in] onetofour Rate for outputs 1 to 4 (Hz)
|
||||
* \param[in] fivetoeight Rate for outputs 5 to 8 (Hz)
|
||||
*/
|
||||
void PIOS_Servo_SetHz(uint16_t * banks, uint8_t num_banks)
|
||||
void PIOS_Servo_SetHz(const uint16_t * banks, uint8_t num_banks)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ static const struct usb_device_desc device_desc = {
|
||||
.bNumConfigurations = 1,
|
||||
};
|
||||
|
||||
static const uint8_t hid_report_desc[36] = {
|
||||
static const uint8_t hid_report_desc[89] = {
|
||||
HID_GLOBAL_ITEM_2 (HID_TAG_GLOBAL_USAGE_PAGE),
|
||||
0x9C, 0xFF, /* Usage Page 0xFF9C (Vendor Defined) */
|
||||
HID_LOCAL_ITEM_1 (HID_TAG_LOCAL_USAGE),
|
||||
@ -93,6 +93,75 @@ static const uint8_t hid_report_desc[36] = {
|
||||
0x82, /* Volatile, Variable */
|
||||
|
||||
HID_MAIN_ITEM_0 (HID_TAG_MAIN_ENDCOLLECTION),
|
||||
|
||||
/* 36 bytes to here */
|
||||
|
||||
/* Emulate a Joystick */
|
||||
HID_GLOBAL_ITEM_1 (HID_TAG_GLOBAL_USAGE_PAGE),
|
||||
0x01, /* Usage Page 0x01 (Generic Desktop Controls) */
|
||||
HID_LOCAL_ITEM_1 (HID_TAG_LOCAL_USAGE),
|
||||
0x04, /* Usage ID 0x0004 (Joystick) */
|
||||
|
||||
HID_GLOBAL_ITEM_1 (HID_TAG_GLOBAL_LOGICAL_MIN),
|
||||
0x00, /* Values range from min = 0x00 */
|
||||
HID_GLOBAL_ITEM_4 (HID_TAG_GLOBAL_LOGICAL_MAX),
|
||||
0xFF, 0xFF, 0x00, 0x00, /* Values range to max = 0x0000FFFF */
|
||||
|
||||
HID_MAIN_ITEM_1 (HID_TAG_MAIN_COLLECTION),
|
||||
0x01, /* Application */
|
||||
HID_MAIN_ITEM_1 (HID_TAG_MAIN_COLLECTION),
|
||||
0x00, /* Physical */
|
||||
HID_GLOBAL_ITEM_1 (HID_TAG_GLOBAL_REPORT_ID),
|
||||
0x03, /* OpenPilot Emulated joystick */
|
||||
|
||||
/* X + Y controls */
|
||||
|
||||
HID_LOCAL_ITEM_1 (HID_TAG_LOCAL_USAGE),
|
||||
0x30, /* Usage ID 0x00010030 (Generic Desktop: X) */
|
||||
HID_LOCAL_ITEM_1 (HID_TAG_LOCAL_USAGE),
|
||||
0x31, /* Usage ID 0x00010031 (Generic Desktop: Y) */
|
||||
HID_GLOBAL_ITEM_1 (HID_TAG_GLOBAL_REPORT_SIZE),
|
||||
0x10, /* 16 bits wide */
|
||||
HID_GLOBAL_ITEM_1 (HID_TAG_GLOBAL_REPORT_CNT),
|
||||
2,
|
||||
HID_MAIN_ITEM_1 (HID_TAG_MAIN_INPUT),
|
||||
0x82, /* Data, Var, Abs, Vol */
|
||||
|
||||
/* Y + Rx controls */
|
||||
|
||||
HID_LOCAL_ITEM_1 (HID_TAG_LOCAL_USAGE),
|
||||
0x32, /* Usage ID 0x00010032 (Generic Desktop: Z) */
|
||||
HID_LOCAL_ITEM_1 (HID_TAG_LOCAL_USAGE),
|
||||
0x33, /* Usage ID 0x00010031 (Generic Desktop: Rx) */
|
||||
HID_GLOBAL_ITEM_1 (HID_TAG_GLOBAL_REPORT_SIZE),
|
||||
0x10, /* 16 bits wide */
|
||||
HID_GLOBAL_ITEM_1 (HID_TAG_GLOBAL_REPORT_CNT),
|
||||
2,
|
||||
HID_MAIN_ITEM_1 (HID_TAG_MAIN_INPUT),
|
||||
0x82, /* Data, Var, Abs, Vol */
|
||||
|
||||
/* Ry, Rz, Slider + Dial controls */
|
||||
|
||||
HID_LOCAL_ITEM_1 (HID_TAG_LOCAL_USAGE),
|
||||
0x34, /* Usage ID 0x00010034 (Generic Desktop: Ry) */
|
||||
HID_LOCAL_ITEM_1 (HID_TAG_LOCAL_USAGE),
|
||||
0x35, /* Usage ID 0x00010035 (Generic Desktop: Rz) */
|
||||
HID_LOCAL_ITEM_1 (HID_TAG_LOCAL_USAGE),
|
||||
0x36, /* Usage ID 0x00010036 (Generic Desktop: Slider) */
|
||||
HID_LOCAL_ITEM_1 (HID_TAG_LOCAL_USAGE),
|
||||
0x37, /* Usage ID 0x00010037 (Generic Desktop: Dial) */
|
||||
HID_GLOBAL_ITEM_1 (HID_TAG_GLOBAL_REPORT_SIZE),
|
||||
0x10, /* 16 bits wide */
|
||||
HID_GLOBAL_ITEM_1 (HID_TAG_GLOBAL_REPORT_CNT),
|
||||
4,
|
||||
HID_MAIN_ITEM_1 (HID_TAG_MAIN_INPUT),
|
||||
0x82, /* Data, Var, Abs, Vol */
|
||||
|
||||
HID_MAIN_ITEM_0 (HID_TAG_MAIN_ENDCOLLECTION),
|
||||
|
||||
HID_MAIN_ITEM_0 (HID_TAG_MAIN_ENDCOLLECTION),
|
||||
|
||||
/* 89 bytes to here */
|
||||
};
|
||||
|
||||
struct usb_config_hid_cdc {
|
||||
|
@ -87,7 +87,7 @@ int32_t PIOS_Servo_Init(const struct pios_servo_cfg * cfg)
|
||||
* \param[in] array of rates in Hz
|
||||
* \param[in] maximum number of banks
|
||||
*/
|
||||
void PIOS_Servo_SetHz(uint16_t * speeds, uint8_t banks)
|
||||
void PIOS_Servo_SetHz(const uint16_t * speeds, uint8_t banks)
|
||||
{
|
||||
if (!servo_cfg) {
|
||||
return;
|
||||
|
211
flight/PiOS/STM32F10x/pios_usb_rctx.c
Normal file
211
flight/PiOS/STM32F10x/pios_usb_rctx.c
Normal file
@ -0,0 +1,211 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @addtogroup PIOS_USB_RCTX USB RC Transmitter/Joystick Functions
|
||||
* @brief PIOS USB implementation for a HID Joystick
|
||||
* @notes This implements transmitter/joystick emulation over HID reports
|
||||
* @{
|
||||
*
|
||||
* @file pios_usb_rctx.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* Project Includes */
|
||||
#include "pios.h"
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_RCTX)
|
||||
|
||||
#include "pios_usb.h"
|
||||
#include "pios_usb_rctx_priv.h"
|
||||
|
||||
/* STM32 USB Library Definitions */
|
||||
#include "usb_lib.h"
|
||||
|
||||
#define PIOS_USB_RCTX_NUM_CHANNELS 8
|
||||
|
||||
enum pios_usb_rctx_dev_magic {
|
||||
PIOS_USB_RCTX_DEV_MAGIC = 0xAB98B745,
|
||||
};
|
||||
|
||||
struct pios_usb_rctx_dev {
|
||||
enum pios_usb_rctx_dev_magic magic;
|
||||
const struct pios_usb_rctx_cfg * cfg;
|
||||
|
||||
uint32_t lower_id;
|
||||
|
||||
struct {
|
||||
uint8_t id;
|
||||
uint16_t vals[PIOS_USB_RCTX_NUM_CHANNELS];
|
||||
} __attribute__((packed)) report;
|
||||
};
|
||||
|
||||
static bool PIOS_USB_RCTX_validate(struct pios_usb_rctx_dev * usb_rctx_dev)
|
||||
{
|
||||
return (usb_rctx_dev->magic == PIOS_USB_RCTX_DEV_MAGIC);
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
static struct pios_usb_rctx_dev * PIOS_USB_RCTX_alloc(void)
|
||||
{
|
||||
struct pios_usb_rctx_dev * usb_rctx_dev;
|
||||
|
||||
usb_rctx_dev = (struct pios_usb_rctx_dev *)pvPortMalloc(sizeof(*usb_rctx_dev));
|
||||
if (!usb_rctx_dev) return(NULL);
|
||||
|
||||
usb_rctx_dev->magic = PIOS_USB_RCTX_DEV_MAGIC;
|
||||
return(usb_rctx_dev);
|
||||
}
|
||||
#else
|
||||
static struct pios_usb_rctx_dev pios_usb_rctx_devs[PIOS_USB_RCTX_MAX_DEVS];
|
||||
static uint8_t pios_usb_rctx_num_devs;
|
||||
static struct pios_usb_rctx_dev * PIOS_USB_RCTX_alloc(void)
|
||||
{
|
||||
struct pios_usb_rctx_dev * usb_rctx_dev;
|
||||
|
||||
if (pios_usb_rctx_num_devs >= PIOS_USB_RCTX_MAX_DEVS) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
usb_rctx_dev = &pios_usb_rctx_devs[pios_usb_rctx_num_devs++];
|
||||
usb_rctx_dev->magic = PIOS_USB_RCTX_DEV_MAGIC;
|
||||
|
||||
return (usb_rctx_dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void PIOS_USB_RCTX_EP_IN_Callback(void);
|
||||
static void PIOS_USB_RCTX_SendReport(struct pios_usb_rctx_dev * usb_rctx_dev);
|
||||
|
||||
/* Need a better way to pull these in */
|
||||
extern void (*pEpInt_IN[7])(void);
|
||||
|
||||
int32_t PIOS_USB_RCTX_Init(uint32_t * usbrctx_id, const struct pios_usb_rctx_cfg * cfg, uint32_t lower_id)
|
||||
{
|
||||
PIOS_Assert(usbrctx_id);
|
||||
PIOS_Assert(cfg);
|
||||
|
||||
struct pios_usb_rctx_dev * usb_rctx_dev;
|
||||
|
||||
usb_rctx_dev = (struct pios_usb_rctx_dev *) PIOS_USB_RCTX_alloc();
|
||||
if (!usb_rctx_dev) goto out_fail;
|
||||
|
||||
/* Bind the configuration to the device instance */
|
||||
usb_rctx_dev->cfg = cfg;
|
||||
usb_rctx_dev->lower_id = lower_id;
|
||||
|
||||
/* Set the initial report buffer */
|
||||
memset(&usb_rctx_dev->report, 0, sizeof(usb_rctx_dev->report));
|
||||
|
||||
pEpInt_IN[cfg->data_tx_ep - 1] = PIOS_USB_RCTX_EP_IN_Callback;
|
||||
|
||||
*usbrctx_id = (uint32_t) usb_rctx_dev;
|
||||
|
||||
return 0;
|
||||
|
||||
out_fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void PIOS_USB_RCTX_SendReport(struct pios_usb_rctx_dev * usb_rctx_dev)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
bool need_yield = false;
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
|
||||
usb_rctx_dev->report.id = 3; /* FIXME: shouldn't hard-code this report ID */
|
||||
|
||||
UserToPMABufferCopy((uint8_t *) &usb_rctx_dev->report,
|
||||
GetEPTxAddr(usb_rctx_dev->cfg->data_tx_ep),
|
||||
sizeof(usb_rctx_dev->report));
|
||||
|
||||
SetEPTxCount(usb_rctx_dev->cfg->data_tx_ep, sizeof(usb_rctx_dev->report));
|
||||
SetEPTxValid(usb_rctx_dev->cfg->data_tx_ep);
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if (need_yield) {
|
||||
vPortYieldFromISR();
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
}
|
||||
|
||||
static void PIOS_USB_RCTX_EP_IN_Callback(void)
|
||||
{
|
||||
struct pios_usb_rctx_dev * usb_rctx_dev = (struct pios_usb_rctx_dev *)pios_usb_rctx_id;
|
||||
|
||||
bool valid = PIOS_USB_RCTX_validate(usb_rctx_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
if (!PIOS_USB_CheckAvailable(usb_rctx_dev->lower_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PIOS_USB_RCTX_SendReport(usb_rctx_dev);
|
||||
}
|
||||
|
||||
void PIOS_USB_RCTX_Update(uint32_t usbrctx_id, const uint16_t channel[], const int16_t channel_min[], const int16_t channel_max[], uint8_t num_channels)
|
||||
{
|
||||
struct pios_usb_rctx_dev * usb_rctx_dev = (struct pios_usb_rctx_dev *)usbrctx_id;
|
||||
|
||||
bool valid = PIOS_USB_RCTX_validate(usb_rctx_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
if (!PIOS_USB_CheckAvailable(usb_rctx_dev->lower_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0;
|
||||
i < PIOS_USB_RCTX_NUM_CHANNELS && i < num_channels;
|
||||
i++) {
|
||||
int16_t min = channel_min[i];
|
||||
int16_t max = channel_max[i];
|
||||
uint16_t val = channel[i];
|
||||
|
||||
if (channel_min[i] > channel_max[i]) {
|
||||
/* This channel is reversed, flip min and max */
|
||||
min = channel_max[i];
|
||||
max = channel_min[i];
|
||||
|
||||
/* and flip val to be an offset from the lower end of the range */
|
||||
val = channel_min[i] - channel[i] + channel_max[i];
|
||||
}
|
||||
|
||||
/* Scale channel linearly between min and max */
|
||||
if (min == max) {
|
||||
val = 0;
|
||||
} else {
|
||||
if (val < min) val = min;
|
||||
if (val > max) val = max;
|
||||
|
||||
val = (val - min) * (65535 / (max - min));
|
||||
}
|
||||
|
||||
usb_rctx_dev->report.vals[i] = val;
|
||||
}
|
||||
|
||||
if (GetEPTxStatus(usb_rctx_dev->cfg->data_tx_ep) == EP_TX_VALID) {
|
||||
/* Endpoint is already transmitting */
|
||||
return;
|
||||
}
|
||||
|
||||
PIOS_USB_RCTX_SendReport(usb_rctx_dev);
|
||||
}
|
||||
|
||||
#endif /* PIOS_INCLUDE_USB_RCTX */
|
@ -87,7 +87,7 @@ int32_t PIOS_Servo_Init(const struct pios_servo_cfg * cfg)
|
||||
* \param[in] array of rates in Hz
|
||||
* \param[in] maximum number of banks
|
||||
*/
|
||||
void PIOS_Servo_SetHz(uint16_t * speeds, uint8_t banks)
|
||||
void PIOS_Servo_SetHz(const uint16_t * speeds, uint8_t banks)
|
||||
{
|
||||
if (!servo_cfg) {
|
||||
return;
|
||||
|
@ -31,7 +31,7 @@
|
||||
#define PIOS_SERVO_H
|
||||
|
||||
/* Public Functions */
|
||||
extern void PIOS_Servo_SetHz(uint16_t * update_rates, uint8_t channels);
|
||||
extern void PIOS_Servo_SetHz(const uint16_t * update_rates, uint8_t banks);
|
||||
extern void PIOS_Servo_Set(uint8_t Servo, uint16_t Position);
|
||||
|
||||
#endif /* PIOS_SERVO_H */
|
||||
|
@ -147,7 +147,7 @@ enum usb_ep_attr {
|
||||
#define HID_LOCAL_ITEM_0(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_LOCAL, HID_ITEM_SIZE_0)
|
||||
#define HID_LOCAL_ITEM_1(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_LOCAL, HID_ITEM_SIZE_1)
|
||||
#define HID_LOCAL_ITEM_2(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_LOCAL, HID_ITEM_SIZE_2)
|
||||
#define HID_LOCAL_ITEM_3(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_LOCAL, HID_ITEM_SIZE_3)
|
||||
#define HID_LOCAL_ITEM_4(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_LOCAL, HID_ITEM_SIZE_4)
|
||||
|
||||
struct usb_device_desc {
|
||||
uint8_t bLength;
|
||||
|
3
flight/PiOS/inc/pios_usb_rctx.h
Normal file
3
flight/PiOS/inc/pios_usb_rctx.h
Normal file
@ -0,0 +1,3 @@
|
||||
extern uint32_t pios_usb_rctx_id;
|
||||
|
||||
extern void PIOS_USB_RCTX_Update(uint32_t usbrctx_id, const uint16_t channel[], const int16_t channel_min[], const int16_t channel_max[], uint8_t num_channels);
|
48
flight/PiOS/inc/pios_usb_rctx_priv.h
Normal file
48
flight/PiOS/inc/pios_usb_rctx_priv.h
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @addtogroup PIOS_USB USB HID RC Transmitter/Joystick
|
||||
* @brief Hardware communication layer
|
||||
* @{
|
||||
*
|
||||
* @file pios_usb_rctx_priv.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @brief USB COM HID private definitions.
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 PIOS_USB_RCTX_PRIV_H
|
||||
#define PIOS_USB_RCTX_PRIV_H
|
||||
|
||||
#include "pios_usb_rctx.h"
|
||||
|
||||
struct pios_usb_rctx_cfg {
|
||||
uint8_t data_if;
|
||||
uint8_t data_tx_ep;
|
||||
};
|
||||
|
||||
extern int32_t PIOS_USB_RCTX_Init(uint32_t * usbrctx_id, const struct pios_usb_rctx_cfg * cfg, uint32_t lower_id);
|
||||
|
||||
#endif /* PIOS_USB_RCTX_PRIV_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
@ -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
|
||||
|
@ -280,6 +280,9 @@ static void eventTask()
|
||||
int32_t delayMs;
|
||||
EventCallbackInfo evInfo;
|
||||
|
||||
/* Must do this in task context to ensure that TaskMonitor has already finished its init */
|
||||
TaskMonitorAdd(TASKINFO_RUNNING_EVENTDISPATCHER, eventTaskHandle);
|
||||
|
||||
// Initialize time
|
||||
timeToNextUpdateMs = xTaskGetTickCount()*portTICK_RATE_MS;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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).
|
||||
|
@ -1284,6 +1284,16 @@ const struct pios_usb_hid_cfg pios_usb_hid_cfg = {
|
||||
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_RCTX)
|
||||
#include <pios_usb_rctx_priv.h>
|
||||
|
||||
const struct pios_usb_rctx_cfg pios_usb_rctx_cfg = {
|
||||
.data_if = 2,
|
||||
.data_tx_ep = 1,
|
||||
};
|
||||
|
||||
#endif /* PIOS_INCLUDE_USB_RCTX */
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_CDC)
|
||||
#include <pios_usb_cdc_priv.h>
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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 |
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -218,17 +218,15 @@ void ConfigGadgetWidget::tabAboutToChange(int i,bool * proceed)
|
||||
*/
|
||||
void ConfigGadgetWidget::updatePipXStatus(UAVObject *object)
|
||||
{
|
||||
|
||||
// Restart the disconnection timer.
|
||||
pipxTimeout->start(5000);
|
||||
if (!pipxConnected)
|
||||
{
|
||||
qDebug()<<"ConfigGadgetWidget onPipxtremeConnect";
|
||||
QWidget *qwd = new ConfigPipXtremeWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::pipxtreme, qwd, QIcon(":/configgadget/images/PipXtreme.png"), QString("PipXtreme"));
|
||||
ftw->setCurrentIndex(ConfigGadgetWidget::pipxtreme);
|
||||
pipxConnected = true;
|
||||
}
|
||||
// Restart the disconnection timer.
|
||||
pipxTimeout->start(5000);
|
||||
if (!pipxConnected)
|
||||
{
|
||||
qDebug()<<"ConfigGadgetWidget onPipxtremeConnect";
|
||||
QWidget *qwd = new ConfigPipXtremeWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::pipxtreme, qwd, QIcon(":/configgadget/images/PipXtreme.png"), QString("PipXtreme"));
|
||||
pipxConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigGadgetWidget::onPipxtremeDisconnect() {
|
||||
|
@ -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");
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -2080,7 +2080,7 @@
|
||||
<plotCurve0>
|
||||
<color>4294901760</color>
|
||||
<mathFunction>None</mathFunction>
|
||||
<uavField>X</uavField>
|
||||
<uavField>x</uavField>
|
||||
<uavObject>Magnetometer</uavObject>
|
||||
<yMaximum>0</yMaximum>
|
||||
<yMeanSamples>1</yMeanSamples>
|
||||
@ -2090,7 +2090,7 @@
|
||||
<plotCurve1>
|
||||
<color>4283782655</color>
|
||||
<mathFunction>None</mathFunction>
|
||||
<uavField>Y</uavField>
|
||||
<uavField>y</uavField>
|
||||
<uavObject>Magnetometer</uavObject>
|
||||
<yMaximum>0</yMaximum>
|
||||
<yMeanSamples>1</yMeanSamples>
|
||||
@ -2100,7 +2100,7 @@
|
||||
<plotCurve2>
|
||||
<color>4283804160</color>
|
||||
<mathFunction>None</mathFunction>
|
||||
<uavField>Z</uavField>
|
||||
<uavField>z</uavField>
|
||||
<uavObject>Magnetometer</uavObject>
|
||||
<yMaximum>0</yMaximum>
|
||||
<yMeanSamples>1</yMeanSamples>
|
||||
|
@ -38,13 +38,7 @@ const quint16 DBG_BUFFER_MAX_SIZE = 4096;
|
||||
#define OBSOLETE_MIT_CHECKBOX (1 << 1)
|
||||
#define OBSOLETE_MIT_SEPARATOR (1 << 7)
|
||||
|
||||
#if defined(Q_CC_MSVC)
|
||||
#define PACK_STRUCT
|
||||
#define MAX_PATH 260
|
||||
#pragma pack (push, r1, 1)
|
||||
#elif defined(Q_CC_GNU)
|
||||
#define PACK_STRUCT __attribute__((packed))
|
||||
#endif
|
||||
|
||||
struct simToPlugin
|
||||
{
|
||||
@ -207,9 +201,6 @@ struct pluginInit
|
||||
const char *strOutputFolder;
|
||||
} PACK_STRUCT ; // normal - 144, packed - 144 OK (3.81 & 3.83 & 3.90)
|
||||
|
||||
#ifdef Q_CC_MSVC
|
||||
#pragma pack (pop, r1)
|
||||
#endif
|
||||
#undef PACK_STRUCT
|
||||
|
||||
#endif // AEROSIMRCDATASTRUCT_H
|
||||
|
@ -15,12 +15,6 @@ SIM_DIR = $$GCS_BUILD_TREE/../AeroSIM-RC
|
||||
PLUGIN_DIR = $$SIM_DIR/Plugin/CopterControl
|
||||
DLLDESTDIR = $$PLUGIN_DIR
|
||||
|
||||
# Don't depend on MSVRT*.dll
|
||||
win32-msvc* {
|
||||
QMAKE_CXXFLAGS_RELEASE -= -MD
|
||||
QMAKE_CXXFLAGS_MT_DLL += -MT
|
||||
}
|
||||
|
||||
HEADERS = \
|
||||
aerosimrcdatastruct.h \
|
||||
enums.h \
|
||||
@ -57,14 +51,20 @@ equals(copydata, 1) {
|
||||
|
||||
# Qt DLLs
|
||||
QT_DLLS = \
|
||||
libgcc_s_dw2-1.dll \
|
||||
mingwm10.dll \
|
||||
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
|
||||
}
|
||||
|
@ -31,9 +31,6 @@
|
||||
#include <QWidget>
|
||||
#include <QUdpSocket>
|
||||
#include <QTime>
|
||||
#if defined(Q_CC_MSVC)
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
#include <qmath.h>
|
||||
#include <QVector3D>
|
||||
#include <QMatrix4x4>
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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()));
|
||||
@ -226,9 +227,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();
|
||||
}
|
||||
@ -1057,7 +1064,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());
|
||||
@ -1131,7 +1138,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);
|
||||
}
|
||||
}
|
||||
@ -1144,33 +1151,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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,12 +144,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;
|
||||
|
@ -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;
|
||||
|
@ -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/
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<field name="TelemetrySpeed" units="bps" type="enum" elements="1" options="2400,4800,9600,19200,38400,57600,115200" defaultvalue="57600"/>
|
||||
<field name="GPSSpeed" units="bps" type="enum" elements="1" options="2400,4800,9600,19200,38400,57600,115200" defaultvalue="57600"/>
|
||||
<field name="ComUsbBridgeSpeed" units="bps" type="enum" elements="1" options="2400,4800,9600,19200,38400,57600,115200" defaultvalue="57600"/>
|
||||
<field name="USB_HIDPort" units="function" type="enum" elements="1" options="USBTelemetry,Disabled" defaultvalue="USBTelemetry"/>
|
||||
<field name="USB_HIDPort" units="function" type="enum" elements="1" options="USBTelemetry,RCTransmitter,Disabled" defaultvalue="USBTelemetry"/>
|
||||
<field name="USB_VCPPort" units="function" type="enum" elements="1" options="USBTelemetry,ComBridge,Disabled" defaultvalue="Disabled"/>
|
||||
|
||||
<field name="OptionalModules" units="" type="enum" elementnames="CameraStab,GPS,ComUsbBridge,Fault,Altitude,Airspeed,TxPID,VtolPathFollower,FixedWingPathFollower,Battery,Overo" options="Disabled,Enabled" defaultvalue="Disabled"/>
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
<!-- Note these options values should be identical to those defined in FlightMode -->
|
||||
<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,ReturnToBase,PathPlanner" defaultvalue="Manual,Stabilized1,Stabilized2,Stabilized3,AltitudeHold,PositionHold"/>
|
||||
<field name="FlightModePosition" units="" type="enum" elements="6" options="Manual,Stabilized1,Stabilized2,Stabilized3,AltitudeHold,VelocityControl,PositionHold,ReturnToBase,PathPlanner" defaultvalue="Manual,Stabilized1,Stabilized2,Stabilized3,AltitudeHold,PositionHold" 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"/>
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<object name="SystemAlarms" singleinstance="true" settings="false">
|
||||
<description>Alarms from OpenPilot to indicate failure conditions or warnings. Set by various modules.</description>
|
||||
<field name="Alarm" units="" type="enum" options="Uninitialised,OK,Warning,Error,Critical"
|
||||
elementnames="OutOfMemory,StackOverflow,CPUOverload,EventSystem,SDCard,Telemetry,ManualControl,Actuator,Attitude,Sensors,Stabilization,Guidance,AHRSComms,Battery,FlightTime,I2C,GPS,BootFault" defaultvalue="Uninitialised"/>
|
||||
elementnames="OutOfMemory,StackOverflow,CPUOverload,EventSystem,Telemetry,ManualControl,Actuator,Attitude,Sensors,Stabilization,Guidance,Battery,FlightTime,I2C,GPS,BootFault" defaultvalue="Uninitialised"/>
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
|
||||
<telemetryflight acked="true" updatemode="onchange" period="0"/>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<xml>
|
||||
<object name="TaskInfo" singleinstance="true" settings="false">
|
||||
<description>Task information</description>
|
||||
<field name="StackRemaining" units="bytes" type="uint16" elementnames="System,Actuator,Attitude,Sensors,TelemetryTx,TelemetryTxPri,TelemetryRx,GPS,ManualControl,Altitude,Airspeed,Stabilization,AltitudeHold,PathPlanner,PathFollower,FlightPlan,Com2UsbBridge,Usb2ComBridge,OveroSync"/>
|
||||
<field name="Running" units="bool" type="enum" options="False,True" elementnames="System,Actuator,Attitude,Sensors,TelemetryTx,TelemetryTxPri,TelemetryRx,GPS,ManualControl,Altitude,Airspeed,Stabilization,AltitudeHold,PathPlanner,PathFollower,FlightPlan,Com2UsbBridge,Usb2ComBridge,OveroSync"/>
|
||||
<field name="RunningTime" units="%" type="uint8" elementnames="System,Actuator,Attitude,Sensors,TelemetryTx,TelemetryTxPri,TelemetryRx,GPS,ManualControl,Altitude,Airspeed,Stabilization,AltitudeHold,PathPlanner,PathFollower,FlightPlan,Com2UsbBridge,Usb2ComBridge,OveroSync"/>
|
||||
<field name="StackRemaining" units="bytes" type="uint16" elementnames="System,Actuator,Attitude,Sensors,TelemetryTx,TelemetryTxPri,TelemetryRx,GPS,ManualControl,Altitude,Airspeed,Stabilization,AltitudeHold,PathPlanner,PathFollower,FlightPlan,Com2UsbBridge,Usb2ComBridge,OveroSync,EventDispatcher"/>
|
||||
<field name="Running" units="bool" type="enum" options="False,True" elementnames="System,Actuator,Attitude,Sensors,TelemetryTx,TelemetryTxPri,TelemetryRx,GPS,ManualControl,Altitude,Airspeed,Stabilization,AltitudeHold,PathPlanner,PathFollower,FlightPlan,Com2UsbBridge,Usb2ComBridge,OveroSync,EventDispatcher"/>
|
||||
<field name="RunningTime" units="%" type="uint8" elementnames="System,Actuator,Attitude,Sensors,TelemetryTx,TelemetryTxPri,TelemetryRx,GPS,ManualControl,Altitude,Airspeed,Stabilization,AltitudeHold,PathPlanner,PathFollower,FlightPlan,Com2UsbBridge,Usb2ComBridge,OveroSync,EventDispatcher"/>
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
|
||||
<telemetryflight acked="true" updatemode="periodic" period="10000"/>
|
||||
|
Loading…
Reference in New Issue
Block a user