1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-30 15:52:12 +01:00

Merge remote-tracking branch 'origin/amorale/OP-1683_syncupdate_oneshot' into next

This commit is contained in:
Alessio Morale 2015-02-08 17:59:59 +01:00
commit 46521f1c2d
19 changed files with 857 additions and 236 deletions

View File

@ -53,20 +53,23 @@ static int8_t counter;
#endif #endif
// Private constants // Private constants
#define MAX_QUEUE_SIZE 2 #define MAX_QUEUE_SIZE 2
#if defined(PIOS_ACTUATOR_STACK_SIZE) #if defined(PIOS_ACTUATOR_STACK_SIZE)
#define STACK_SIZE_BYTES PIOS_ACTUATOR_STACK_SIZE #define STACK_SIZE_BYTES PIOS_ACTUATOR_STACK_SIZE
#else #else
#define STACK_SIZE_BYTES 1312 #define STACK_SIZE_BYTES 1312
#endif #endif
#define TASK_PRIORITY (tskIDLE_PRIORITY + 4) // device driver #define TASK_PRIORITY (tskIDLE_PRIORITY + 4) // device driver
#define FAILSAFE_TIMEOUT_MS 100 #define FAILSAFE_TIMEOUT_MS 100
#define MAX_MIX_ACTUATORS ACTUATORCOMMAND_CHANNEL_NUMELEM #define MAX_MIX_ACTUATORS ACTUATORCOMMAND_CHANNEL_NUMELEM
#define CAMERA_BOOT_DELAY_MS 7000 #define CAMERA_BOOT_DELAY_MS 7000
#define ACTUATOR_ONESHOT125_CLOCK 2000000
#define ACTUATOR_ONESHOT125_PULSE_SCALE 4
#define ACTUATOR_PWM_CLOCK 1000000
// Private types // Private types
@ -74,8 +77,9 @@ static int8_t counter;
static xQueueHandle queue; static xQueueHandle queue;
static xTaskHandle taskHandle; static xTaskHandle taskHandle;
static float lastResult[MAX_MIX_ACTUATORS] = { 0, 0, 0, 0, 0, 0, 0, 0 }; static float lastResult[MAX_MIX_ACTUATORS] = { 0 };
static float filterAccumulator[MAX_MIX_ACTUATORS] = { 0, 0, 0, 0, 0, 0, 0, 0 }; static float filterAccumulator[MAX_MIX_ACTUATORS] = { 0 };
static uint8_t pinsMode[MAX_MIX_ACTUATORS];
// used to inform the actuator thread that actuator update rate is changed // used to inform the actuator thread that actuator update rate is changed
static volatile bool actuator_settings_updated; static volatile bool actuator_settings_updated;
// used to inform the actuator thread that mixer settings are changed // used to inform the actuator thread that mixer settings are changed
@ -436,7 +440,6 @@ static void actuatorTask(__attribute__((unused)) void *parameters)
if (command.UpdateTime > command.MaxUpdateTime) { if (command.UpdateTime > command.MaxUpdateTime) {
command.MaxUpdateTime = command.UpdateTime; command.MaxUpdateTime = command.UpdateTime;
} }
// Update output object // Update output object
ActuatorCommandSet(&command); ActuatorCommandSet(&command);
// Update in case read only (eg. during servo configuration) // Update in case read only (eg. during servo configuration)
@ -454,6 +457,8 @@ static void actuatorTask(__attribute__((unused)) void *parameters)
success &= set_channel(n, command.Channel[n], &actuatorSettings); success &= set_channel(n, command.Channel[n], &actuatorSettings);
} }
PIOS_Servo_Update();
if (!success) { if (!success) {
command.NumFailedUpdates++; command.NumFailedUpdates++;
ActuatorCommandSet(&command); ActuatorCommandSet(&command);
@ -476,11 +481,11 @@ float ProcessMixer(const int index, const float curve1, const float curve2,
const 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
const Mixer_t *mixer = &mixers[index]; const Mixer_t *mixer = &mixers[index];
float result = (((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_THROTTLECURVE1] / 128.0f) * curve1) + float result = ((((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_THROTTLECURVE1]) * curve1) +
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_THROTTLECURVE2] / 128.0f) * curve2) + (((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_THROTTLECURVE2]) * curve2) +
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_ROLL] / 128.0f) * desired->Roll) + (((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_ROLL]) * desired->Roll) +
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_PITCH] / 128.0f) * desired->Pitch) + (((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_PITCH]) * desired->Pitch) +
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_YAW] / 128.0f) * desired->Yaw); (((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_YAW]) * desired->Yaw)) / 128.0f;
// note: no feedforward for reversable motors yet for safety reasons // note: no feedforward for reversable motors yet for safety reasons
if (mixer->type == MIXERSETTINGS_MIXER1TYPE_MOTOR) { if (mixer->type == MIXERSETTINGS_MIXER1TYPE_MOTOR) {
@ -615,6 +620,8 @@ static void setFailsafe(const ActuatorSettingsData *actuatorSettings, const Mixe
for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n) { for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n) {
set_channel(n, Channel[n], actuatorSettings); set_channel(n, Channel[n], actuatorSettings);
} }
// Send the updated command
PIOS_Servo_Update();
// Update output object's parts that we changed // Update output object's parts that we changed
ActuatorCommandChannelSet(Channel); ActuatorCommandChannelSet(Channel);
@ -730,8 +737,19 @@ static bool set_channel(uint8_t mixer_channel, uint16_t value, const ActuatorSet
return true; return true;
case ACTUATORSETTINGS_CHANNELTYPE_PWM: case ACTUATORSETTINGS_CHANNELTYPE_PWM:
PIOS_Servo_Set(actuatorSettings->ChannelAddr[mixer_channel], value); {
uint8_t mode = pinsMode[actuatorSettings->ChannelAddr[mixer_channel]];
switch (mode) {
case ACTUATORSETTINGS_BANKMODE_ONESHOT125:
// Remap 1000-2000 range to 125-250
PIOS_Servo_Set(actuatorSettings->ChannelAddr[mixer_channel], value / ACTUATOR_ONESHOT125_PULSE_SCALE);
break;
default:
PIOS_Servo_Set(actuatorSettings->ChannelAddr[mixer_channel], value);
break;
}
return true; return true;
}
#if defined(PIOS_INCLUDE_I2C_ESC) #if defined(PIOS_INCLUDE_I2C_ESC)
case ACTUATORSETTINGS_CHANNELTYPE_MK: case ACTUATORSETTINGS_CHANNELTYPE_MK:
@ -754,18 +772,57 @@ static bool set_channel(uint8_t mixer_channel, uint16_t value, const ActuatorSet
*/ */
static void actuator_update_rate_if_changed(const ActuatorSettingsData *actuatorSettings, bool force_update) static void actuator_update_rate_if_changed(const ActuatorSettingsData *actuatorSettings, bool force_update)
{ {
static uint16_t prevChannelUpdateFreq[ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM]; static uint16_t prevBankUpdateFreq[ACTUATORSETTINGS_BANKUPDATEFREQ_NUMELEM];
static uint8_t prevBankMode[ACTUATORSETTINGS_BANKMODE_NUMELEM];
// check if the any rate setting is changed // check if the any rate setting is changed
if (force_update || if (force_update ||
memcmp(prevChannelUpdateFreq, (memcmp(prevBankUpdateFreq,
actuatorSettings->ChannelUpdateFreq, actuatorSettings->BankUpdateFreq,
sizeof(prevChannelUpdateFreq)) != 0) { sizeof(prevBankUpdateFreq)) != 0) ||
(memcmp(prevBankUpdateFreq,
actuatorSettings->BankMode,
sizeof(prevBankMode)) != 0)
) {
/* Something has changed, apply the settings to HW */ /* Something has changed, apply the settings to HW */
memcpy(prevChannelUpdateFreq, memcpy(prevBankUpdateFreq,
actuatorSettings->ChannelUpdateFreq, actuatorSettings->BankUpdateFreq,
sizeof(prevChannelUpdateFreq)); sizeof(prevBankUpdateFreq));
PIOS_Servo_SetHz(actuatorSettings->ChannelUpdateFreq, ACTUATORSETTINGS_CHANNELUPDATEFREQ_NUMELEM); memcpy(prevBankMode,
actuatorSettings->BankMode,
sizeof(prevBankMode));
uint16_t freq[ACTUATORSETTINGS_BANKUPDATEFREQ_NUMELEM];
uint32_t clock[ACTUATORSETTINGS_BANKUPDATEFREQ_NUMELEM] = { 0 };
for (uint8_t i = 0; i < ACTUATORSETTINGS_BANKMODE_NUMELEM; i++) {
PIOS_Servo_SetBankMode(i,
actuatorSettings->BankMode[i] ==
ACTUATORSETTINGS_BANKMODE_PWM ?
PIOS_SERVO_BANK_MODE_PWM :
PIOS_SERVO_BANK_MODE_SINGLE_PULSE
);
switch (actuatorSettings->BankMode[i]) {
case ACTUATORSETTINGS_BANKMODE_ONESHOT125:
freq[i] = 100; // Value must be small enough so CCr isn't update until the PIOS_Servo_Update is triggered
clock[i] = ACTUATOR_ONESHOT125_CLOCK; // Setup an 8MHz timer clock
break;
case ACTUATORSETTINGS_BANKMODE_ONESHOT:
freq[i] = 100;
clock[i] = ACTUATOR_PWM_CLOCK;
break;
default: // PWM
freq[i] = actuatorSettings->BankUpdateFreq[i];
clock[i] = ACTUATOR_PWM_CLOCK;
break;
}
}
PIOS_Servo_SetHz(freq, clock, ACTUATORSETTINGS_BANKUPDATEFREQ_NUMELEM);
// retrieve mode from related bank
for (uint8_t i = 0; i < MAX_MIX_ACTUATORS; i++) {
uint8_t bank = PIOS_Servo_GetPinBank(i);
pinsMode[i] = actuatorSettings->BankMode[bank];
}
} }
} }

View File

@ -30,9 +30,17 @@
#ifndef PIOS_SERVO_H #ifndef PIOS_SERVO_H
#define PIOS_SERVO_H #define PIOS_SERVO_H
/* Global types */
enum pios_servo_bank_mode {
PIOS_SERVO_BANK_MODE_PWM = 0,
PIOS_SERVO_BANK_MODE_SINGLE_PULSE = 1
};
/* Public Functions */ /* Public Functions */
extern void PIOS_Servo_SetHz(const uint16_t *update_rates, uint8_t banks); extern void PIOS_Servo_SetHz(const uint16_t *speeds, const uint32_t *clock, uint8_t banks);
extern void PIOS_Servo_Set(uint8_t Servo, uint16_t Position); extern void PIOS_Servo_Set(uint8_t Servo, uint16_t Position);
extern void PIOS_Servo_Update();
extern void PIOS_Servo_SetBankMode(uint8_t bank, uint8_t mode);
extern uint8_t PIOS_Servo_GetPinBank(uint8_t pin);
#endif /* PIOS_SERVO_H */ #endif /* PIOS_SERVO_H */

View File

@ -43,13 +43,13 @@ static volatile uint16_t ServoPosition[PIOS_SERVO_NUM_TIMERS];
*/ */
void PIOS_Servo_Init(void) void PIOS_Servo_Init(void)
{} {}
/** /**
* Set the servo update rate (Max 500Hz) * Set the servo update rate (Max 500Hz)
* \param[in] onetofour Rate for outputs 1 to 4 (Hz) * \param[in] array of rates in Hz
* \param[in] fivetoeight Rate for outputs 5 to 8 (Hz) * \param[in] array of timer clocks in Hz
* \param[in] maximum number of banks
*/ */
void PIOS_Servo_SetHz(const uint16_t *banks, uint8_t num_banks) void PIOS_Servo_SetHz(const uint16_t *speeds, const uint32_t *clock, uint8_t banks)
{} {}
/** /**

View File

@ -39,6 +39,17 @@
static const struct pios_servo_cfg *servo_cfg; static const struct pios_servo_cfg *servo_cfg;
// determine if the related timer will work in synchronous (or OneShot/OneShot125) One Pulse mode.
// static uint8_t pios_servo_bank_mode[PIOS_SERVO_BANKS] = { 0 };
// timer associated to each bank
static TIM_TypeDef *pios_servo_bank_timer[PIOS_SERVO_BANKS] = { 0 };
// index of bank used for each pin
static uint8_t *pios_servo_pin_bank;
#define PIOS_SERVO_TIMER_CLOCK 1000000
/** /**
* Initialise Servos * Initialise Servos
*/ */
@ -52,10 +63,36 @@ int32_t PIOS_Servo_Init(const struct pios_servo_cfg *cfg)
/* Store away the requested configuration */ /* Store away the requested configuration */
servo_cfg = cfg; servo_cfg = cfg;
pios_servo_pin_bank = pios_malloc(sizeof(uint8_t) * cfg->num_channels);
uint8_t bank = 0;
/* Configure the channels to be in output compare mode */ /* Configure the channels to be in output compare mode */
for (uint8_t i = 0; i < cfg->num_channels; i++) { for (uint8_t i = 0; i < cfg->num_channels; i++) {
const struct pios_tim_channel *chan = &cfg->channels[i]; const struct pios_tim_channel *chan = &servo_cfg->channels[i];
bool new = true;
/* See if any previous channels use that same timer */
for (uint8_t j = 0; (j < i) && new; j++) {
new &= chan->timer != servo_cfg->channels[j].timer;
}
if (new) {
PIOS_Assert(bank < PIOS_SERVO_BANKS);
for (uint8_t j = i; j < servo_cfg->num_channels; j++) {
if (servo_cfg->channels[j].timer == chan->timer) {
pios_servo_pin_bank[j] = bank;
}
}
pios_servo_bank_timer[bank] = chan->timer;
PIOS_Assert(bank < PIOS_SERVO_BANKS);
for (uint8_t j = i; j < servo_cfg->num_channels; j++) {
if (servo_cfg->channels[j].timer == chan->timer) {
pios_servo_pin_bank[j] = bank;
}
}
bank++;
}
/* Set up for output compare function */ /* Set up for output compare function */
switch (chan->timer_chan) { switch (chan->timer_chan) {
@ -88,10 +125,12 @@ int32_t PIOS_Servo_Init(const struct pios_servo_cfg *cfg)
/** /**
* Set the servo update rate (Max 500Hz) * Set the servo update rate (Max 500Hz)
* \param[in] array of rates in Hz * \param[in] array of rates in Hz
* \param[in] array of timer clocks in Hz
* \param[in] maximum number of banks * \param[in] maximum number of banks
*/ */
void PIOS_Servo_SetHz(const uint16_t *speeds, uint8_t banks) void PIOS_Servo_SetHz(const uint16_t *speeds, const uint32_t *clock, uint8_t banks)
{ {
PIOS_Assert(banks <= PIOS_SERVO_BANKS);
if (!servo_cfg) { if (!servo_cfg) {
return; return;
} }
@ -99,23 +138,18 @@ void PIOS_Servo_SetHz(const uint16_t *speeds, uint8_t banks)
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = servo_cfg->tim_base_init; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = servo_cfg->tim_base_init;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1;
uint8_t set = 0; for (uint8_t i = 0; i < banks && i < PIOS_SERVO_BANKS; i++) {
const TIM_TypeDef *timer = pios_servo_bank_timer[i];
if (timer) {
uint32_t new_clock = PIOS_SERVO_TIMER_CLOCK;
if (clock[i]) {
new_clock = clock[i];
}
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_MASTER_CLOCK / new_clock) - 1;
TIM_TimeBaseStructure.TIM_Period = ((new_clock / speeds[i]) - 1);
for (uint8_t i = 0; (i < servo_cfg->num_channels) && (set < banks); i++) { TIM_TimeBaseInit((TIM_TypeDef *)timer, &TIM_TimeBaseStructure);
bool new = true;
const struct pios_tim_channel *chan = &servo_cfg->channels[i];
/* See if any previous channels use that same timer */
for (uint8_t j = 0; (j < i) && new; j++) {
new &= chan->timer != servo_cfg->channels[j].timer;
}
if (new) {
TIM_TimeBaseStructure.TIM_Period = ((1000000 / speeds[set]) - 1);
TIM_TimeBaseInit(chan->timer, &TIM_TimeBaseStructure);
set++;
} }
} }
} }
@ -150,4 +184,27 @@ void PIOS_Servo_Set(uint8_t servo, uint16_t position)
} }
} }
void PIOS_Servo_Update()
{
/*
for (uint8_t i = 0; (i < PIOS_SERVO_BANKS); i++) {
const TIM_TypeDef *timer = pios_servo_bank_timer[i];
if (timer) {
TIM_Cmd((TIM_TypeDef *)timer, ENABLE);
}
}
*/
}
void PIOS_Servo_SetBankMode(__attribute__((unused)) uint8_t bank, __attribute__((unused)) uint8_t mode) {}
uint8_t PIOS_Servo_GetPinBank(uint8_t pin)
{
if (pin < servo_cfg->num_channels) {
return pios_servo_pin_bank[pin];
} else {
return 0;
}
}
#endif /* PIOS_INCLUDE_SERVO */ #endif /* PIOS_INCLUDE_SERVO */

View File

@ -39,6 +39,19 @@
static const struct pios_servo_cfg *servo_cfg; static const struct pios_servo_cfg *servo_cfg;
// determine if the related timer will work in synchronous (or OneShot/OneShot125) One Pulse mode.
static uint8_t pios_servo_bank_mode[PIOS_SERVO_BANKS] = { 0 };
// used to skip updates when pulse length is higher than update cycle
static uint16_t pios_servo_bank_next_update[PIOS_SERVO_BANKS] = { 0 };
static uint16_t pios_servo_bank_max_pulse[PIOS_SERVO_BANKS] = { 0 };
// timer associated to each bank
static TIM_TypeDef *pios_servo_bank_timer[PIOS_SERVO_BANKS] = { 0 };
// index of bank used for each pin
static uint8_t *pios_servo_pin_bank;
#define PIOS_SERVO_TIMER_CLOCK 1000000
#define PIOS_SERVO_SAFE_MARGIN 50
/** /**
* Initialise Servos * Initialise Servos
*/ */
@ -52,46 +65,141 @@ int32_t PIOS_Servo_Init(const struct pios_servo_cfg *cfg)
/* Store away the requested configuration */ /* Store away the requested configuration */
servo_cfg = cfg; servo_cfg = cfg;
pios_servo_pin_bank = pios_malloc(sizeof(uint8_t) * cfg->num_channels);
/* Configure the channels to be in output compare mode */ uint8_t bank = 0;
for (uint8_t i = 0; i < cfg->num_channels; i++) { for (uint8_t i = 0; (i < servo_cfg->num_channels); i++) {
const struct pios_tim_channel *chan = &cfg->channels[i]; const struct pios_tim_channel *chan = &servo_cfg->channels[i];
bool new = true;
/* See if any previous channels use that same timer */
for (uint8_t j = 0; (j < i) && new; j++) {
new &= chan->timer != servo_cfg->channels[j].timer;
}
if (new) {
PIOS_Assert(bank < PIOS_SERVO_BANKS);
for (uint8_t j = i; j < servo_cfg->num_channels; j++) {
if (servo_cfg->channels[j].timer == chan->timer) {
pios_servo_pin_bank[j] = bank;
}
}
pios_servo_bank_timer[bank] = chan->timer;
TIM_ARRPreloadConfig(chan->timer, ENABLE);
TIM_CtrlPWMOutputs(chan->timer, ENABLE);
TIM_Cmd(chan->timer, DISABLE);
bank++;
}
/* Set up for output compare function */ /* Set up for output compare function */
switch (chan->timer_chan) { switch (chan->timer_chan) {
case TIM_Channel_1: case TIM_Channel_1:
TIM_OC1Init(chan->timer, &cfg->tim_oc_init); TIM_OC1Init(chan->timer, &servo_cfg->tim_oc_init);
TIM_OC1PreloadConfig(chan->timer, TIM_OCPreload_Enable); TIM_OC1PreloadConfig(chan->timer, TIM_OCPreload_Enable);
break; break;
case TIM_Channel_2: case TIM_Channel_2:
TIM_OC2Init(chan->timer, &cfg->tim_oc_init); TIM_OC2Init(chan->timer, &servo_cfg->tim_oc_init);
TIM_OC2PreloadConfig(chan->timer, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(chan->timer, TIM_OCPreload_Enable);
break; break;
case TIM_Channel_3: case TIM_Channel_3:
TIM_OC3Init(chan->timer, &cfg->tim_oc_init); TIM_OC3Init(chan->timer, &servo_cfg->tim_oc_init);
TIM_OC3PreloadConfig(chan->timer, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(chan->timer, TIM_OCPreload_Enable);
break; break;
case TIM_Channel_4: case TIM_Channel_4:
TIM_OC4Init(chan->timer, &cfg->tim_oc_init); TIM_OC4Init(chan->timer, &servo_cfg->tim_oc_init);
TIM_OC4PreloadConfig(chan->timer, TIM_OCPreload_Enable); TIM_OC4PreloadConfig(chan->timer, TIM_OCPreload_Enable);
break; break;
} }
TIM_ARRPreloadConfig(chan->timer, ENABLE);
TIM_CtrlPWMOutputs(chan->timer, ENABLE);
TIM_Cmd(chan->timer, ENABLE);
} }
return 0; return 0;
} }
void PIOS_Servo_SetBankMode(uint8_t bank, uint8_t mode)
{
PIOS_Assert(bank < PIOS_SERVO_BANKS);
pios_servo_bank_mode[bank] = mode;
if (pios_servo_bank_timer[bank]) {
for (uint8_t i = 0; (i < servo_cfg->num_channels); i++) {
if (pios_servo_pin_bank[i] == bank) {
const struct pios_tim_channel *chan = &servo_cfg->channels[i];
/* Set up for output compare function */
switch (chan->timer_chan) {
case TIM_Channel_1:
TIM_OC1PolarityConfig(chan->timer, TIM_OCPolarity_High);
break;
case TIM_Channel_2:
TIM_OC2PolarityConfig(chan->timer, TIM_OCPolarity_High);
break;
case TIM_Channel_3:
TIM_OC3PolarityConfig(chan->timer, TIM_OCPolarity_High);
break;
case TIM_Channel_4:
TIM_OC4PolarityConfig(chan->timer, TIM_OCPolarity_High);
break;
}
}
}
if (mode != PIOS_SERVO_BANK_MODE_PWM) {
// TIM_UpdateDisableConfig(pios_servo_bank_timer[bank], ENABLE);
} else {
// TIM_UpdateDisableConfig(pios_servo_bank_timer[bank], DISABLE);
}
// Setup the timer accordingly
TIM_SelectOnePulseMode(pios_servo_bank_timer[bank], TIM_OPMode_Repetitive);
TIM_Cmd(pios_servo_bank_timer[bank], ENABLE);
}
}
void PIOS_Servo_Update()
{
for (uint8_t i = 0; (i < PIOS_SERVO_BANKS); i++) {
const TIM_TypeDef *timer = pios_servo_bank_timer[i];
if (timer && pios_servo_bank_mode[i] == PIOS_SERVO_BANK_MODE_SINGLE_PULSE) {
// a pulse to be generated is longer than cycle period. skip this update.
if (TIM_GetCounter((TIM_TypeDef *)timer) > (uint32_t)(pios_servo_bank_next_update[i] + PIOS_SERVO_SAFE_MARGIN)) {
TIM_GenerateEvent((TIM_TypeDef *)timer, TIM_EventSource_Update);
pios_servo_bank_next_update[i] = pios_servo_bank_max_pulse[i];
}
}
pios_servo_bank_max_pulse[i] = 0;
}
for (uint8_t i = 0; (i < servo_cfg->num_channels); i++) {
uint8_t bank = pios_servo_pin_bank[i];
uint8_t mode = pios_servo_bank_mode[bank];
if (mode == PIOS_SERVO_BANK_MODE_SINGLE_PULSE) {
/* Update the position */
const struct pios_tim_channel *chan = &servo_cfg->channels[i];
switch (chan->timer_chan) {
case TIM_Channel_1:
TIM_SetCompare1(chan->timer, 0);
break;
case TIM_Channel_2:
TIM_SetCompare2(chan->timer, 0);
break;
case TIM_Channel_3:
TIM_SetCompare3(chan->timer, 0);
break;
case TIM_Channel_4:
TIM_SetCompare4(chan->timer, 0);
break;
}
}
}
}
/** /**
* Set the servo update rate (Max 500Hz) * Set the servo update rate (Max 500Hz)
* \param[in] array of rates in Hz * \param[in] array of rates in Hz
* \param[in] array of timer clocks in Hz
* \param[in] maximum number of banks * \param[in] maximum number of banks
*/ */
void PIOS_Servo_SetHz(const uint16_t *speeds, uint8_t banks) void PIOS_Servo_SetHz(const uint16_t *speeds, const uint32_t *clock, uint8_t banks)
{ {
PIOS_Assert(banks <= PIOS_SERVO_BANKS);
if (!servo_cfg) { if (!servo_cfg) {
return; return;
} }
@ -99,30 +207,22 @@ void PIOS_Servo_SetHz(const uint16_t *speeds, uint8_t banks)
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = servo_cfg->tim_base_init; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = servo_cfg->tim_base_init;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//
uint8_t set = 0; for (uint8_t i = 0; i < banks && i < PIOS_SERVO_BANKS; i++) {
const TIM_TypeDef *timer = pios_servo_bank_timer[i];
for (uint8_t i = 0; (i < servo_cfg->num_channels) && (set < banks); i++) { if (timer) {
bool new = true; uint32_t new_clock = PIOS_SERVO_TIMER_CLOCK;
const struct pios_tim_channel *chan = &servo_cfg->channels[i]; if (clock[i]) {
new_clock = clock[i];
/* See if any previous channels use that same timer */
for (uint8_t j = 0; (j < i) && new; j++) {
new &= chan->timer != servo_cfg->channels[j].timer;
}
if (new) {
// Choose the correct prescaler value for the APB the timer is attached
if (chan->timer == TIM1 || chan->timer == TIM8 || chan->timer == TIM9 || chan->timer == TIM10 || chan->timer == TIM11) {
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_PERIPHERAL_APB2_CLOCK / 1000000) - 1;
} else {
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_PERIPHERAL_APB1_CLOCK / 1000000) - 1;
} }
// Choose the correct prescaler value for the APB the timer is attached
TIM_TimeBaseStructure.TIM_Period = ((1000000 / speeds[set]) - 1); if (timer == TIM1 || timer == TIM8 || timer == TIM9 || timer == TIM10 || timer == TIM11) {
TIM_TimeBaseInit(chan->timer, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_PERIPHERAL_APB2_CLOCK / new_clock) - 1;
set++; } else {
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_PERIPHERAL_APB1_CLOCK / new_clock) - 1;
}
TIM_TimeBaseStructure.TIM_Period = ((new_clock / speeds[i]) - 1);
TIM_TimeBaseInit((TIM_TypeDef *)timer, &TIM_TimeBaseStructure);
} }
} }
} }
@ -139,22 +239,42 @@ void PIOS_Servo_Set(uint8_t servo, uint16_t position)
return; return;
} }
/* Update the position */ /* Update the position */
const struct pios_tim_channel *chan = &servo_cfg->channels[servo]; const struct pios_tim_channel *chan = &servo_cfg->channels[servo];
uint16_t val = position;
uint16_t margin = chan->timer->ARR / 50; // Leave 2% of period as margin to prevent overlaps
if (val > (chan->timer->ARR - margin)) {
val = chan->timer->ARR - margin;
}
uint8_t bank = pios_servo_pin_bank[servo];
if (pios_servo_bank_max_pulse[bank] < val) {
pios_servo_bank_max_pulse[bank] = val;
}
switch (chan->timer_chan) { switch (chan->timer_chan) {
case TIM_Channel_1: case TIM_Channel_1:
TIM_SetCompare1(chan->timer, position); TIM_SetCompare1(chan->timer, val);
break; break;
case TIM_Channel_2: case TIM_Channel_2:
TIM_SetCompare2(chan->timer, position); TIM_SetCompare2(chan->timer, val);
break; break;
case TIM_Channel_3: case TIM_Channel_3:
TIM_SetCompare3(chan->timer, position); TIM_SetCompare3(chan->timer, val);
break; break;
case TIM_Channel_4: case TIM_Channel_4:
TIM_SetCompare4(chan->timer, position); TIM_SetCompare4(chan->timer, val);
break; break;
} }
} }
uint8_t PIOS_Servo_GetPinBank(uint8_t pin)
{
if (pin < servo_cfg->num_channels) {
return pios_servo_pin_bank[pin];
} else {
return 0;
}
}
#endif /* PIOS_INCLUDE_SERVO */ #endif /* PIOS_INCLUDE_SERVO */

View File

@ -251,6 +251,7 @@ extern uint32_t pios_com_hkosd_id;
// ------------------------- // -------------------------
#define PIOS_SERVO_UPDATE_HZ 50 #define PIOS_SERVO_UPDATE_HZ 50
#define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */ #define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */
#define PIOS_SERVO_BANKS 6
// -------------------------- // --------------------------
// Timer controller settings // Timer controller settings

View File

@ -248,6 +248,7 @@ extern uint32_t pios_packet_handler;
// ------------------------- // -------------------------
#define PIOS_SERVO_UPDATE_HZ 50 #define PIOS_SERVO_UPDATE_HZ 50
#define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */ #define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */
#define PIOS_SERVO_BANKS 6
// -------------------------- // --------------------------
// Timer controller settings // Timer controller settings

View File

@ -260,6 +260,7 @@ extern uint32_t pios_ppm_out_id;
// ------------------------- // -------------------------
#define PIOS_SERVO_UPDATE_HZ 50 #define PIOS_SERVO_UPDATE_HZ 50
#define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */ #define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */
#define PIOS_SERVO_BANKS 6
// -------------------------- // --------------------------
// Timer controller settings // Timer controller settings

View File

@ -247,6 +247,8 @@ extern uint32_t pios_com_telem_usb_id;
// -------------------------- // --------------------------
#define PIOS_TIM_MAX_DEVS 6 #define PIOS_TIM_MAX_DEVS 6
#define PIOS_SERVO_BANKS 6
// ------------------------- // -------------------------
// USB // USB
// ------------------------- // -------------------------

View File

@ -268,7 +268,7 @@ extern uint32_t pios_packet_handler;
// ------------------------- // -------------------------
#define PIOS_SERVO_UPDATE_HZ 50 #define PIOS_SERVO_UPDATE_HZ 50
#define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */ #define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */
#define PIOS_SERVO_BANKS 6
// -------------------------- // --------------------------
// Timer controller settings // Timer controller settings
// -------------------------- // --------------------------

View File

@ -225,6 +225,7 @@ extern uint32_t pios_com_hkosd_id;
// ------------------------- // -------------------------
#define PIOS_SERVO_UPDATE_HZ 50 #define PIOS_SERVO_UPDATE_HZ 50
#define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */ #define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */
#define PIOS_SERVO_BANKS 6
// -------------------------- // --------------------------
// Timer controller settings // Timer controller settings

View File

@ -98,9 +98,18 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
addWidget(ui->cb_outputRate1); addWidget(ui->cb_outputRate1);
addWidget(ui->spinningArmed); addWidget(ui->spinningArmed);
addWidgetBinding("ActuatorSettings", "BankMode", ui->cb_outputMode1, 0, 0, true);
addWidgetBinding("ActuatorSettings", "BankMode", ui->cb_outputMode2, 1, 0, true);
addWidgetBinding("ActuatorSettings", "BankMode", ui->cb_outputMode3, 2, 0, true);
addWidgetBinding("ActuatorSettings", "BankMode", ui->cb_outputMode4, 3, 0, true);
addWidgetBinding("ActuatorSettings", "BankMode", ui->cb_outputMode5, 4, 0, true);
addWidgetBinding("ActuatorSettings", "BankMode", ui->cb_outputMode6, 5, 0, true);
disconnect(this, SLOT(refreshWidgetsValues(UAVObject *))); disconnect(this, SLOT(refreshWidgetsValues(UAVObject *)));
populateWidgets();
refreshWidgetsValues(); refreshWidgetsValues();
updateEnableControls(); updateEnableControls();
} }
@ -240,6 +249,17 @@ void ConfigOutputWidget::sendChannelTest(int index, int value)
actuatorCommand->setData(actuatorCommandFields); actuatorCommand->setData(actuatorCommandFields);
} }
void ConfigOutputWidget::setColor(QWidget *widget, const QColor color)
{
QPalette p(palette());
p.setColor(QPalette::Background, color);
p.setColor(QPalette::Base, color);
p.setColor(QPalette::Active, QPalette::Button, color);
p.setColor(QPalette::Inactive, QPalette::Button, color);
widget->setAutoFillBackground(true);
widget->setPalette(p);
}
/******************************** /********************************
* Output settings * Output settings
@ -250,22 +270,33 @@ void ConfigOutputWidget::sendChannelTest(int index, int value)
*/ */
void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj) void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj)
{ {
Q_UNUSED(obj);
bool dirty = isDirty(); bool dirty = isDirty();
ConfigTaskWidget::refreshWidgetsValues(obj);
// Get Actuator Settings // Get Actuator Settings
ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager()); ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
Q_ASSERT(actuatorSettings); Q_ASSERT(actuatorSettings);
ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData(); ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData();
// Get channel descriptions // Get channel descriptions
QStringList ChannelDesc = ConfigVehicleTypeWidget::getChannelDescriptions(); QStringList channelDesc = ConfigVehicleTypeWidget::getChannelDescriptions();
QList<int> channelBanks;
QList<QColor> bankColors;
bankColors
<< QColor("#C6ECAE")
<< QColor("#91E5D3")
<< QColor("#FCEC52")
<< QColor("#C3A8FF")
<< QColor("#F7F7F2")
<< QColor("#FF9F51");
// Initialize output forms // Initialize output forms
QList<OutputChannelForm *> outputChannelForms = findChildren<OutputChannelForm *>(); QList<OutputChannelForm *> outputChannelForms = findChildren<OutputChannelForm *>();
foreach(OutputChannelForm * outputChannelForm, outputChannelForms) { foreach(OutputChannelForm * outputChannelForm, outputChannelForms) {
outputChannelForm->setName(ChannelDesc[outputChannelForm->index()]); outputChannelForm->setName(channelDesc[outputChannelForm->index()]);
// init min,max,neutral // init min,max,neutral
int minValue = actuatorSettingsData.ChannelMin[outputChannelForm->index()]; int minValue = actuatorSettingsData.ChannelMin[outputChannelForm->index()];
@ -279,89 +310,78 @@ void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj)
// Get the SpinWhileArmed setting // Get the SpinWhileArmed setting
ui->spinningArmed->setChecked(actuatorSettingsData.MotorsSpinWhileArmed == ActuatorSettings::MOTORSSPINWHILEARMED_TRUE); ui->spinningArmed->setChecked(actuatorSettingsData.MotorsSpinWhileArmed == ActuatorSettings::MOTORSSPINWHILEARMED_TRUE);
// Setup output rates for all banks QList<QLabel *> bank;
if (ui->cb_outputRate1->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[0])) == -1) { bank << ui->chBank1 << ui->chBank2 << ui->chBank3 << ui->chBank4 << ui->chBank5 << ui->chBank6;
ui->cb_outputRate1->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[0]));
}
if (ui->cb_outputRate2->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[1])) == -1) {
ui->cb_outputRate2->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[1]));
}
if (ui->cb_outputRate3->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[2])) == -1) {
ui->cb_outputRate3->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[2]));
}
if (ui->cb_outputRate4->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[3])) == -1) {
ui->cb_outputRate4->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[3]));
}
if (ui->cb_outputRate5->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[4])) == -1) {
ui->cb_outputRate5->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[4]));
}
if (ui->cb_outputRate6->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[5])) == -1) {
ui->cb_outputRate6->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[5]));
}
ui->cb_outputRate1->setCurrentIndex(ui->cb_outputRate1->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[0])));
ui->cb_outputRate2->setCurrentIndex(ui->cb_outputRate2->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[1])));
ui->cb_outputRate3->setCurrentIndex(ui->cb_outputRate3->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[2])));
ui->cb_outputRate4->setCurrentIndex(ui->cb_outputRate4->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[3])));
ui->cb_outputRate5->setCurrentIndex(ui->cb_outputRate5->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[4])));
ui->cb_outputRate6->setCurrentIndex(ui->cb_outputRate6->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[5])));
// Reset to all disabled QList<QComboBox *> outputRateCombos;
ui->chBank1->setText("-"); outputRateCombos << ui->cb_outputRate1 << ui->cb_outputRate2 << ui->cb_outputRate3 <<
ui->chBank2->setText("-"); ui->cb_outputRate4 << ui->cb_outputRate5 << ui->cb_outputRate6;
ui->chBank3->setText("-");
ui->chBank4->setText("-"); QList<QComboBox *> outputModeCombos;
ui->chBank5->setText("-"); outputModeCombos << ui->cb_outputMode1 << ui->cb_outputMode2 << ui->cb_outputMode3 <<
ui->chBank6->setText("-"); ui->cb_outputMode4 << ui->cb_outputMode5 << ui->cb_outputMode6;
ui->cb_outputRate1->setEnabled(false);
ui->cb_outputRate2->setEnabled(false); Q_ASSERT(outputModeCombos.count() == outputRateCombos.count());
ui->cb_outputRate3->setEnabled(false); Q_ASSERT(outputRateCombos.count() == bank.count());
ui->cb_outputRate4->setEnabled(false);
ui->cb_outputRate5->setEnabled(false); for(int i = 0; i < outputModeCombos.count();i++){
ui->cb_outputRate6->setEnabled(false); // Setup output rates for all banks
if (outputRateCombos.at(i)->findText(QString::number(actuatorSettingsData.BankUpdateFreq[i])) == -1) {
outputRateCombos.at(i)->addItem(QString::number(actuatorSettingsData.BankUpdateFreq[i]));
}
outputRateCombos.at(i)->setCurrentIndex(outputRateCombos.at(i)->findText(QString::number(actuatorSettingsData.BankUpdateFreq[i])));
// Reset to all disabled
bank.at(i)->setText("-");
outputRateCombos.at(i)->setEnabled(false);
setColor(outputRateCombos.at(i), palette().color(QPalette::Background));
outputModeCombos.at(i)->setEnabled(false);
setColor(outputModeCombos.at(i), palette().color(QPalette::Background));
}
// Get connected board model // Get connected board model
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Q_ASSERT(pm); Q_ASSERT(pm);
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>(); UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
Q_ASSERT(utilMngr); Q_ASSERT(utilMngr);
QStringList bankLabels;
if (utilMngr) { if (utilMngr) {
int board = utilMngr->getBoardModel(); int board = utilMngr->getBoardModel();
// Setup labels and combos for banks according to board type // Setup labels and combos for banks according to board type
if ((board & 0xff00) == 0x0400) { if ((board & 0xff00) == 0x0400) {
// Coptercontrol family of boards 4 timer banks // Coptercontrol family of boards 4 timer banks
ui->chBank1->setText("1-3"); bankLabels << "1 (1-3)" << "2 (4)" << "3 (5,7-8)" << "4 (6,9-10)";
ui->chBank2->setText("4"); channelBanks << 1 << 1 << 1 << 2 << 3 << 4 << 3 << 3 << 4 << 4;
ui->chBank3->setText("5,7-8");
ui->chBank4->setText("6,9-10");
ui->cb_outputRate1->setEnabled(true);
ui->cb_outputRate2->setEnabled(true);
ui->cb_outputRate3->setEnabled(true);
ui->cb_outputRate4->setEnabled(true);
} else if ((board & 0xff00) == 0x0900) { } else if ((board & 0xff00) == 0x0900) {
// Revolution family of boards 6 timer banks // Revolution family of boards 6 timer banks
ui->chBank1->setText("1-2"); bankLabels << "1 (1-2)" << "2 (3)" << "3 (4)" << "4 (5-6)" << "5 (7-8)" << "6 (9-10)";
ui->chBank2->setText("3"); channelBanks << 1 << 1 << 2 << 3 << 4 << 4 << 5 << 5 << 6 << 6;
ui->chBank3->setText("4");
ui->chBank4->setText("5-6");
ui->chBank5->setText("7-8");
ui->chBank6->setText("9-10");
ui->cb_outputRate1->setEnabled(true);
ui->cb_outputRate2->setEnabled(true);
ui->cb_outputRate3->setEnabled(true);
ui->cb_outputRate4->setEnabled(true);
ui->cb_outputRate5->setEnabled(true);
ui->cb_outputRate6->setEnabled(true);
} }
} }
int i = 0;
foreach(QString banklabel, bankLabels) {
bank[i]->setText(banklabel);
outputRateCombos[i]->setEnabled(true);
setColor(outputRateCombos[i], bankColors[i]);
outputModeCombos[i]->setEnabled(true);
setColor(outputModeCombos[i], bankColors[i]);
i++;
}
// Get Channel ranges: // Get Channel ranges:
i = 0;
foreach(OutputChannelForm * outputChannelForm, outputChannelForms) { foreach(OutputChannelForm * outputChannelForm, outputChannelForms) {
int minValue = actuatorSettingsData.ChannelMin[outputChannelForm->index()]; int minValue = actuatorSettingsData.ChannelMin[outputChannelForm->index()];
int maxValue = actuatorSettingsData.ChannelMax[outputChannelForm->index()]; int maxValue = actuatorSettingsData.ChannelMax[outputChannelForm->index()];
outputChannelForm->setRange(minValue, maxValue); outputChannelForm->setRange(minValue, maxValue);
if (channelBanks.count() > i) {
outputChannelForm->setBank(QString("%1").arg(channelBanks.at(i)));
outputChannelForm->setColor(bankColors[channelBanks.at(i++) - 1]);
}
int neutral = actuatorSettingsData.ChannelNeutral[outputChannelForm->index()]; int neutral = actuatorSettingsData.ChannelNeutral[outputChannelForm->index()];
outputChannelForm->setNeutral(neutral); outputChannelForm->setNeutral(neutral);
} }
@ -374,7 +394,7 @@ void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj)
*/ */
void ConfigOutputWidget::updateObjectsFromWidgets() void ConfigOutputWidget::updateObjectsFromWidgets()
{ {
emit updateObjectsFromWidgetsRequested(); ConfigTaskWidget::updateObjectsFromWidgets();
ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager()); ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
@ -391,12 +411,12 @@ void ConfigOutputWidget::updateObjectsFromWidgets()
} }
// Set update rates // Set update rates
actuatorSettingsData.ChannelUpdateFreq[0] = ui->cb_outputRate1->currentText().toUInt(); actuatorSettingsData.BankUpdateFreq[0] = ui->cb_outputRate1->currentText().toUInt();
actuatorSettingsData.ChannelUpdateFreq[1] = ui->cb_outputRate2->currentText().toUInt(); actuatorSettingsData.BankUpdateFreq[1] = ui->cb_outputRate2->currentText().toUInt();
actuatorSettingsData.ChannelUpdateFreq[2] = ui->cb_outputRate3->currentText().toUInt(); actuatorSettingsData.BankUpdateFreq[2] = ui->cb_outputRate3->currentText().toUInt();
actuatorSettingsData.ChannelUpdateFreq[3] = ui->cb_outputRate4->currentText().toUInt(); actuatorSettingsData.BankUpdateFreq[3] = ui->cb_outputRate4->currentText().toUInt();
actuatorSettingsData.ChannelUpdateFreq[4] = ui->cb_outputRate5->currentText().toUInt(); actuatorSettingsData.BankUpdateFreq[4] = ui->cb_outputRate5->currentText().toUInt();
actuatorSettingsData.ChannelUpdateFreq[5] = ui->cb_outputRate6->currentText().toUInt(); actuatorSettingsData.BankUpdateFreq[5] = ui->cb_outputRate6->currentText().toUInt();
actuatorSettingsData.MotorsSpinWhileArmed = ui->spinningArmed->isChecked() ? actuatorSettingsData.MotorsSpinWhileArmed = ui->spinningArmed->isChecked() ?
ActuatorSettings::MOTORSSPINWHILEARMED_TRUE : ActuatorSettings::MOTORSSPINWHILEARMED_TRUE :

View File

@ -59,6 +59,8 @@ private:
void assignOutputChannel(UAVDataObject *obj, QString &str); void assignOutputChannel(UAVDataObject *obj, QString &str);
void setColor(QWidget *widget, const QColor color);
OutputChannelForm *getOutputChannelForm(const int index) const; OutputChannelForm *getOutputChannelForm(const int index) const;
void sendAllChannelTests(); void sendAllChannelTests();

View File

@ -122,8 +122,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>674</width> <width>680</width>
<height>677</height> <height>672</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
@ -157,7 +157,7 @@
</size> </size>
</property> </property>
<property name="title"> <property name="title">
<string>Output Update Speed</string> <string>Output configuration</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="6"> <item row="0" column="6">
@ -183,7 +183,7 @@
<item row="0" column="1"> <item row="0" column="1">
<widget class="QLabel" name="label_9"> <widget class="QLabel" name="label_9">
<property name="text"> <property name="text">
<string>Channel:</string> <string>Bank(Channels):</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -282,9 +282,15 @@
</size> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Setup &quot;RapidESC&quot; here: usual value is 490 Hz for multirotor airframes. <string>Setup PWM rate here: usual value is 490 Hz for multirotor airframes. OneShot and OneShot125 does not use this value
</string> </string>
</property> </property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<item> <item>
<property name="text"> <property name="text">
<string>50</string> <string>50</string>
@ -345,8 +351,10 @@
</size> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Setup &quot;RapidESC&quot; here: usual value is 490 Hz for multirotor airframes. <string>Setup PWM rate here: usual value is 490 Hz for multirotor airframes. OneShot and OneShot125 does not use this value</string>
</string> </property>
<property name="styleSheet">
<string notr="true"/>
</property> </property>
<item> <item>
<property name="text"> <property name="text">
@ -430,8 +438,10 @@
</size> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Setup &quot;RapidESC&quot; here: usual value is 490 Hz for multirotor airframes. <string>Setup PWM rate here: usual value is 490 Hz for multirotor airframes. OneShot and OneShot125 does not use this value</string>
</string> </property>
<property name="styleSheet">
<string notr="true"/>
</property> </property>
<item> <item>
<property name="text"> <property name="text">
@ -493,8 +503,10 @@
</size> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Setup &quot;RapidESC&quot; here: usual value is 490 Hz for multirotor airframes. <string>Setup PWM rate here: usual value is 490 Hz for multirotor airframes. OneShot and OneShot125 does not use this value</string>
</string> </property>
<property name="styleSheet">
<string notr="true"/>
</property> </property>
<item> <item>
<property name="text"> <property name="text">
@ -566,8 +578,10 @@
</size> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Setup &quot;RapidESC&quot; here: usual value is 490 Hz for multirotor airframes. <string>Setup PWM rate here: usual value is 490 Hz for multirotor airframes. OneShot and OneShot125 does not use this value</string>
</string> </property>
<property name="styleSheet">
<string notr="true"/>
</property> </property>
<item> <item>
<property name="text"> <property name="text">
@ -629,8 +643,10 @@
</size> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Setup &quot;RapidESC&quot; here: usual value is 490 Hz for multirotor airframes. <string>Setup PWM rate here: usual value is 490 Hz for multirotor airframes. OneShot and OneShot125 does not use this value</string>
</string> </property>
<property name="styleSheet">
<string notr="true"/>
</property> </property>
<item> <item>
<property name="text"> <property name="text">
@ -674,6 +690,190 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<spacer name="horizontalSpacer_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>Mode:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="cb_outputMode1">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="toolTip">
<string>Setup output mode. Use PWM or OneShot with Standard ESCs.
Several other ESCs like BLHeli 13+ can use the more advanced OneShot125.
When using OneShot125 all values set in min/max and idle are divided by eight before being sent to esc (i.e. 1000 = 125, 2000 = 250).</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QComboBox" name="cb_outputMode2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="toolTip">
<string>Setup output mode. Use PWM or OneShot with Standard ESCs.\nSeveral other ESCs like BLHeli 13+ can use the more advanced OneShot125.\nWhen using OneShot125 all values set in min/max and idle are divided by eight before being sent to esc (i.e. 1000 = 125, 2000 = 250).</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QComboBox" name="cb_outputMode3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="toolTip">
<string>Setup output mode. Use PWM or OneShot with Standard ESCs.\nSeveral other ESCs like BLHeli 13+ can use the more advanced OneShot125.\nWhen using OneShot125 all values set in min/max and idle are divided by eight before being sent to esc (i.e. 1000 = 125, 2000 = 250).</string>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QComboBox" name="cb_outputMode4">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="toolTip">
<string>Setup output mode. Use PWM or OneShot with Standard ESCs.\nSeveral other ESCs like BLHeli 13+ can use the more advanced OneShot125.\nWhen using OneShot125 all values set in min/max and idle are divided by eight before being sent to esc (i.e. 1000 = 125, 2000 = 250).</string>
</property>
</widget>
</item>
<item row="2" column="6">
<widget class="QComboBox" name="cb_outputMode5">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="toolTip">
<string>Setup output mode. Use PWM or OneShot with Standard ESCs.\nSeveral other ESCs like BLHeli 13+ can use the more advanced OneShot125.\nWhen using OneShot125 all values set in min/max and idle are divided by eight before being sent to esc (i.e. 1000 = 125, 2000 = 250).</string>
</property>
</widget>
</item>
<item row="2" column="7">
<widget class="QComboBox" name="cb_outputMode6">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="toolTip">
<string>Setup output mode. Use PWM or OneShot with Standard ESCs.\nSeveral other ESCs like BLHeli 13+ can use the more advanced OneShot125.\nWhen using OneShot125 all values set in min/max and idle are divided by eight before being sent to esc (i.e. 1000 = 125, 2000 = 250).</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@ -33,8 +33,8 @@ OutputChannelForm::OutputChannelForm(const int index, QWidget *parent) :
ui.setupUi(this); ui.setupUi(this);
// The convention for OP is Channel 1 to Channel 10. // The convention for OP is Channel 1 to Channel 10.
ui.actuatorNumber->setText(QString("%1:").arg(index + 1)); ui.actuatorNumber->setText(QString("%1").arg(index + 1));
setBank("-");
// Register for ActuatorSettings changes: // Register for ActuatorSettings changes:
connect(ui.actuatorMin, SIGNAL(editingFinished()), this, SLOT(setChannelRange())); connect(ui.actuatorMin, SIGNAL(editingFinished()), this, SLOT(setChannelRange()));
connect(ui.actuatorMax, SIGNAL(editingFinished()), this, SLOT(setChannelRange())); connect(ui.actuatorMax, SIGNAL(editingFinished()), this, SLOT(setChannelRange()));
@ -58,6 +58,11 @@ QString OutputChannelForm::name()
return ui.actuatorName->text(); return ui.actuatorName->text();
} }
QString OutputChannelForm::bank()
{
return ui.actuatorBankNumber->text();
}
/** /**
* Set the channel assignment label. * Set the channel assignment label.
*/ */
@ -66,6 +71,25 @@ void OutputChannelForm::setName(const QString &name)
ui.actuatorName->setText(name); ui.actuatorName->setText(name);
} }
void OutputChannelForm::setColor(const QColor &color)
{
QString stylesheet = ui.actuatorNumberFrame->styleSheet();
stylesheet = stylesheet.split("background-color").first();
stylesheet.append(
QString("background-color: rgb(%1, %2, %3)")
.arg(color.red()).arg(color.green()).arg(color.blue()));
ui.actuatorNumberFrame->setStyleSheet(stylesheet);
}
/**
* Set the channel bank label.
*/
void OutputChannelForm::setBank(const QString &bank)
{
ui.actuatorBankNumber->setText(bank);
}
/** /**
* Restrict UI to protect users from accidental misuse. * Restrict UI to protect users from accidental misuse.
*/ */

View File

@ -43,8 +43,12 @@ public:
friend class ConfigOutputWidget; friend class ConfigOutputWidget;
virtual QString name(); virtual QString name();
virtual void setName(const QString &name); virtual QString bank();
virtual void setName(const QString &name);
virtual void setBank(const QString &bank);
virtual void setColor(const QColor &color);
public slots: public slots:
int min() const; int min() const;
void setMin(int minimum); void setMin(int minimum);

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>768</width> <width>768</width>
<height>51</height> <height>54</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -29,7 +29,7 @@
<property name="horizontalSpacing"> <property name="horizontalSpacing">
<number>12</number> <number>12</number>
</property> </property>
<item row="0" column="1"> <item row="0" column="2">
<widget class="QLabel" name="legend0"> <widget class="QLabel" name="legend0">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -72,7 +72,7 @@ margin:1px;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="2"> <item row="0" column="3">
<widget class="QLabel" name="legend1"> <widget class="QLabel" name="legend1">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -115,7 +115,7 @@ margin:1px;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="4"> <item row="0" column="5">
<widget class="QLabel" name="legend2"> <widget class="QLabel" name="legend2">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -152,7 +152,7 @@ margin:1px;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="5"> <item row="0" column="6">
<spacer name="horizontalSpacer_4"> <spacer name="horizontalSpacer_4">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -168,7 +168,7 @@ margin:1px;</string>
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="0" column="0"> <item row="0" column="0" colspan="2">
<widget class="QLabel" name="legend6"> <widget class="QLabel" name="legend6">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -207,7 +207,7 @@ font: bold 12px;
margin:1px;</string> margin:1px;</string>
</property> </property>
<property name="text"> <property name="text">
<string>#</string> <string> # - Bank</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignCenter</set> <set>Qt::AlignCenter</set>
@ -217,7 +217,7 @@ margin:1px;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="3"> <item row="0" column="4">
<spacer name="horizontalSpacer_3"> <spacer name="horizontalSpacer_3">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -233,7 +233,7 @@ margin:1px;</string>
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="1" column="5"> <item row="1" column="6">
<spacer name="horizontalSpacer_2"> <spacer name="horizontalSpacer_2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -249,7 +249,7 @@ margin:1px;</string>
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="1" column="3"> <item row="1" column="4">
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -265,7 +265,7 @@ margin:1px;</string>
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="1" column="2"> <item row="1" column="3">
<widget class="QSpinBox" name="actuatorMin"> <widget class="QSpinBox" name="actuatorMin">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -289,7 +289,8 @@ margin:1px;</string>
<enum>Qt::StrongFocus</enum> <enum>Qt::StrongFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Minimum PWM value, beware of not overdriving your servo.</string> <string>Minimum PWM value, beware of not overdriving your servo.
Using OneShot125 a value of 1000(uS) here will produce a pulse of 125(uS).</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -302,38 +303,151 @@ margin:1px;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0" colspan="2">
<widget class="QLabel" name="actuatorNumber"> <widget class="QFrame" name="actuatorNumberFrame">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred"> <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>16777215</width> <width>100</width>
<height>16777215</height> <height>22</height>
</size> </size>
</property> </property>
<property name="toolTip"> <property name="styleSheet">
<string>Channel Number</string> <string notr="true">border-radius: 5; margin:1px;</string>
</property> </property>
<property name="text"> <property name="frameShape">
<string>0:</string> <enum>QFrame::NoFrame</enum>
</property> </property>
<property name="alignment"> <property name="frameShadow">
<set>Qt::AlignCenter</set> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QHBoxLayout">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="actuatorNumber">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="toolTip">
<string>Channel Number</string>
</property>
<property name="styleSheet">
<string notr="true">border-radius: 5;\nfont: bold 12px;\nmargin:1px;</string>
</property>
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">border-radius: 5;\nfont: 12px;\nmargin:1px;</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="actuatorBankNumber">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Bank number</string>
</property>
<property name="styleSheet">
<string notr="true">border-radius: 5;\nfont: 12px;\nmargin:1px;</string>
</property>
<property name="text">
<string> 0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</item> </item>
<item row="0" column="6"> <item row="0" column="7">
<widget class="QLabel" name="legend3"> <widget class="QLabel" name="legend3">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -376,7 +490,7 @@ margin:1px;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="7"> <item row="0" column="8">
<widget class="QLabel" name="legend4"> <widget class="QLabel" name="legend4">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -419,7 +533,7 @@ margin:1px;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="8"> <item row="0" column="9">
<widget class="QLabel" name="legend5"> <widget class="QLabel" name="legend5">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -462,7 +576,7 @@ margin:1px;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="2">
<widget class="QLabel" name="actuatorName"> <widget class="QLabel" name="actuatorName">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred"> <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
@ -490,7 +604,7 @@ margin:1px;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="6"> <item row="1" column="7">
<widget class="QSpinBox" name="actuatorMax"> <widget class="QSpinBox" name="actuatorMax">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -514,7 +628,8 @@ margin:1px;</string>
<enum>Qt::StrongFocus</enum> <enum>Qt::StrongFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Maximum PWM value, beware of not overdriving your servo.</string> <string>Maximum value, beware of not overdriving your servo.
Using OneShot125 a value of 2000(uS) here will produce a pulse of 250(uS).</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -524,8 +639,8 @@ margin:1px;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="4"> <item row="1" column="5">
<widget class="QFrame" name="frame"> <widget class="QFrame" name="barFrame">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -607,7 +722,7 @@ margin:1px;</string>
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="1" column="7"> <item row="1" column="8">
<widget class="QFrame" name="frame_1"> <widget class="QFrame" name="frame_1">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred"> <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
@ -665,7 +780,7 @@ margin:1px;</string>
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="1" column="8"> <item row="1" column="9">
<widget class="QFrame" name="frame_2"> <widget class="QFrame" name="frame_2">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred"> <sizepolicy hsizetype="Minimum" vsizetype="Preferred">

View File

@ -404,32 +404,32 @@ void VehicleConfigurationHelper::applyActuatorConfiguration()
data.MotorsSpinWhileArmed = ActuatorSettings::MOTORSSPINWHILEARMED_FALSE; data.MotorsSpinWhileArmed = ActuatorSettings::MOTORSSPINWHILEARMED_FALSE;
for (quint16 i = 0; i < ActuatorSettings::CHANNELUPDATEFREQ_NUMELEM; i++) { for (quint16 i = 0; i < ActuatorSettings::BANKUPDATEFREQ_NUMELEM; i++) {
data.ChannelUpdateFreq[i] = LEGACY_ESC_FREQUENCY; data.BankUpdateFreq[i] = LEGACY_ESC_FREQUENCY;
} }
switch (m_configSource->getVehicleSubType()) { switch (m_configSource->getVehicleSubType()) {
case VehicleConfigurationSource::MULTI_ROTOR_TRI_Y: case VehicleConfigurationSource::MULTI_ROTOR_TRI_Y:
// Servo always on channel 4 // Servo always on channel 4
data.ChannelUpdateFreq[0] = escFrequence; data.BankUpdateFreq[0] = escFrequence;
if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_CC || if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_CC ||
m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_CC3D) { m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_CC3D) {
data.ChannelUpdateFreq[1] = servoFrequence; data.BankUpdateFreq[1] = servoFrequence;
} else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) { } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
data.ChannelUpdateFreq[1] = escFrequence; data.BankUpdateFreq[1] = escFrequence;
data.ChannelUpdateFreq[2] = servoFrequence; data.BankUpdateFreq[2] = servoFrequence;
} else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) { } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) {
data.ChannelUpdateFreq[1] = escFrequence; data.BankUpdateFreq[1] = escFrequence;
data.ChannelUpdateFreq[2] = escFrequence; data.BankUpdateFreq[2] = escFrequence;
data.ChannelUpdateFreq[3] = servoFrequence; data.BankUpdateFreq[3] = servoFrequence;
} }
break; break;
case VehicleConfigurationSource::MULTI_ROTOR_QUAD_X: case VehicleConfigurationSource::MULTI_ROTOR_QUAD_X:
case VehicleConfigurationSource::MULTI_ROTOR_QUAD_PLUS: case VehicleConfigurationSource::MULTI_ROTOR_QUAD_PLUS:
data.ChannelUpdateFreq[0] = escFrequence; data.BankUpdateFreq[0] = escFrequence;
data.ChannelUpdateFreq[1] = escFrequence; data.BankUpdateFreq[1] = escFrequence;
if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) { if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
data.ChannelUpdateFreq[2] = escFrequence; data.BankUpdateFreq[2] = escFrequence;
} }
break; break;
case VehicleConfigurationSource::MULTI_ROTOR_HEXA: case VehicleConfigurationSource::MULTI_ROTOR_HEXA:
@ -441,10 +441,10 @@ void VehicleConfigurationHelper::applyActuatorConfiguration()
case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_X: case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_X:
case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_PLUS: case VehicleConfigurationSource::MULTI_ROTOR_OCTO_COAX_PLUS:
case VehicleConfigurationSource::MULTI_ROTOR_OCTO_V: case VehicleConfigurationSource::MULTI_ROTOR_OCTO_V:
data.ChannelUpdateFreq[0] = escFrequence; data.BankUpdateFreq[0] = escFrequence;
data.ChannelUpdateFreq[1] = escFrequence; data.BankUpdateFreq[1] = escFrequence;
data.ChannelUpdateFreq[2] = escFrequence; data.BankUpdateFreq[2] = escFrequence;
data.ChannelUpdateFreq[3] = escFrequence; data.BankUpdateFreq[3] = escFrequence;
break; break;
default: default:
break; break;
@ -467,15 +467,15 @@ void VehicleConfigurationHelper::applyActuatorConfiguration()
data.ChannelMax[i] = actuatorSettings[i].channelMax; data.ChannelMax[i] = actuatorSettings[i].channelMax;
} }
for (quint16 i = 0; i < ActuatorSettings::CHANNELUPDATEFREQ_NUMELEM; i++) { for (quint16 i = 0; i < ActuatorSettings::BANKUPDATEFREQ_NUMELEM; i++) {
data.ChannelUpdateFreq[i] = servoFrequence; data.BankUpdateFreq[i] = servoFrequence;
if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) { if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
if (i == 1) { if (i == 1) {
data.ChannelUpdateFreq[i] = escFrequence; data.BankUpdateFreq[i] = escFrequence;
} }
} else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) { } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) {
if (i == 2) { if (i == 2) {
data.ChannelUpdateFreq[i] = escFrequence; data.BankUpdateFreq[i] = escFrequence;
} }
} }
} }
@ -503,15 +503,15 @@ void VehicleConfigurationHelper::applyActuatorConfiguration()
data.ChannelMax[i] = actuatorSettings[i].channelMax; data.ChannelMax[i] = actuatorSettings[i].channelMax;
} }
for (quint16 i = 0; i < ActuatorSettings::CHANNELUPDATEFREQ_NUMELEM; i++) { for (quint16 i = 0; i < ActuatorSettings::BANKUPDATEFREQ_NUMELEM; i++) {
data.ChannelUpdateFreq[i] = servoFrequence; data.BankUpdateFreq[i] = servoFrequence;
if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) { if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
if (i == 1) { if (i == 1) {
data.ChannelUpdateFreq[i] = escFrequence; data.BankUpdateFreq[i] = escFrequence;
} }
} else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) { } else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) {
if (i == 2) { if (i == 2) {
data.ChannelUpdateFreq[i] = escFrequence; data.BankUpdateFreq[i] = escFrequence;
} }
} }
} }

View File

@ -1,7 +1,15 @@
<xml> <xml>
<object name="ActuatorSettings" singleinstance="true" settings="true" category="Control"> <object name="ActuatorSettings" singleinstance="true" settings="true" category="Control">
<description>Settings for the @ref ActuatorModule that controls the channel assignments for the mixer based on AircraftType</description> <description>Settings for the @ref ActuatorModule that controls the channel assignments for the mixer based on AircraftType</description>
<field name="ChannelUpdateFreq" units="Hz" type="uint16" elements="6" defaultvalue="50"/> <field name="BankUpdateFreq" units="Hz" type="uint16" elements="6" defaultvalue="50"/>
<field name="BankMode" type="enum" units="" elements="6" options="PWM,OneShot,OneShot125" defaultvalue="PWM"
limits="%0401NE:OneShot:OneShot125,%0402NE:OneShot:OneShot125; \
%0401NE:OneShot:OneShot125,%0402NE:OneShot:OneShot125; \
%0401NE:OneShot:OneShot125,%0402NE:OneShot:OneShot125; \
%0401NE:OneShot:OneShot125,%0402NE:OneShot:OneShot125; \
%0401NE:OneShot:OneShot125,%0402NE:OneShot:OneShot125; \
%0401NE:OneShot:OneShot125,%0402NE:OneShot:OneShot125;"
/>
<field name="ChannelMax" units="us" type="int16" elements="12" defaultvalue="1000"/> <field name="ChannelMax" units="us" type="int16" elements="12" defaultvalue="1000"/>
<field name="ChannelNeutral" units="us" type="int16" elements="12" defaultvalue="1000"/> <field name="ChannelNeutral" units="us" type="int16" elements="12" defaultvalue="1000"/>
<field name="ChannelMin" units="us" type="int16" elements="12" defaultvalue="1000"/> <field name="ChannelMin" units="us" type="int16" elements="12" defaultvalue="1000"/>