diff --git a/Makefile b/Makefile index 7fa2fc0d5..60fe7b1ab 100644 --- a/Makefile +++ b/Makefile @@ -847,6 +847,7 @@ docs_all_clean: .PHONY: build-info build-info: + @$(ECHO) " BUILD-INFO $(call toprel, $(BUILD_DIR)/$@.txt)" $(V1) $(MKDIR) -p $(BUILD_DIR) $(V1) $(VERSION_INFO) \ --uavodir=$(ROOT_DIR)/shared/uavobjectdefinition \ diff --git a/flight/libraries/inc/packet_handler.h b/flight/libraries/inc/packet_handler.h index 603ca3d12..5e04884ad 100644 --- a/flight/libraries/inc/packet_handler.h +++ b/flight/libraries/inc/packet_handler.h @@ -76,7 +76,7 @@ typedef struct { #define PH_PPM_DATA_SIZE(p) ((uint8_t*)((p)->ecc) - (uint8_t*)(((PHPacketHandle)(p))->data)) typedef struct { PHPacketHeader header; - uint16_t channels[PIOS_RFM22B_RCVR_MAX_CHANNELS]; + int16_t channels[PIOS_RFM22B_RCVR_MAX_CHANNELS]; uint8_t ecc[RS_ECC_NPARITY]; } PHPpmPacket, *PHPpmPacketHandle; diff --git a/flight/modules/Osd/OsdEtStd/OsdEtStd.c b/flight/modules/Osd/OsdEtStd/OsdEtStd.c index edd148942..a1e4a5d69 100644 --- a/flight/modules/Osd/OsdEtStd/OsdEtStd.c +++ b/flight/modules/Osd/OsdEtStd/OsdEtStd.c @@ -41,7 +41,7 @@ // #define DEBUG_PORT PIOS_COM_GPS //#define ENABLE_DEBUG_MSG -//#define USE_DEBUG_PINS +//#define PIOS_ENABLE_DEBUG_PINS //#define DUMP_CONFIG // Enable this do read and dump the OSD config // @@ -78,7 +78,7 @@ #define OSDMSG_GPS_STAT_FIX 0x2B #define OSDMSG_GPS_STAT_HB_FLAG 0x10 -#ifdef USE_DEBUG_PINS +#ifdef PIOS_ENABLE_DEBUG_PINS #define DEBUG_PIN_RUNNING 0 #define DEBUG_PIN_I2C 1 #define DebugPinHigh(x) PIOS_DEBUG_PinHigh(x) diff --git a/flight/modules/RadioComBridge/RadioComBridge.c b/flight/modules/RadioComBridge/RadioComBridge.c index ccb6199ef..ea1579c6f 100644 --- a/flight/modules/RadioComBridge/RadioComBridge.c +++ b/flight/modules/RadioComBridge/RadioComBridge.c @@ -91,6 +91,9 @@ typedef struct { // Should we parse UAVTalk? bool parseUAVTalk; + // We can only configure the hardware once. + bool configured; + // The current configured uart speed OPLinkSettingsComSpeedOptions comSpeed; @@ -232,6 +235,7 @@ static int32_t RadioComBridgeInitialize(void) data->comTxRetries = 0; data->UAVTalkErrors = 0; data->parseUAVTalk = false; + data->configured = false; data->comSpeed = OPLINKSETTINGS_COMSPEED_9600; PIOS_COM_RADIO = PIOS_COM_RFM22B; @@ -590,6 +594,12 @@ static void updateSettings() OPLinkSettingsData oplinkSettings; OPLinkSettingsGet(&oplinkSettings); + // We can only configure the hardware once. + if (data->configured) { + return; + } + data->configured = true; + // Configure the main port bool is_coordinator = PIOS_RFM22B_IsCoordinator(pios_rfm22b_id); switch (oplinkSettings.MainPort) { diff --git a/flight/pios/common/pios_rfm22b.c b/flight/pios/common/pios_rfm22b.c index 30be8fbd5..c236fe622 100644 --- a/flight/pios/common/pios_rfm22b.c +++ b/flight/pios/common/pios_rfm22b.c @@ -2072,9 +2072,9 @@ static void rfm22_sendPPM(struct pios_rfm22b_dev *rfm22b_dev) // See if we have any valid channels. bool valid_input_detected = false; - for (uint8_t i = 1; i <= PIOS_PPM_NUM_INPUTS; ++i) { - rfm22b_dev->ppm_packet.channels[i - 1] = PIOS_RCVR_Read(PIOS_PPM_RECEIVER, i); - if(rfm22b_dev->ppm_packet.channels[i - 1] != PIOS_RCVR_TIMEOUT) + for (uint8_t i = 0; i < PIOS_PPM_NUM_INPUTS; ++i) { + rfm22b_dev->ppm_packet.channels[i] = PIOS_RCVR_Read(PIOS_PPM_RECEIVER, i + 1); + if((rfm22b_dev->ppm_packet.channels[i] != PIOS_RCVR_INVALID) && (rfm22b_dev->ppm_packet.channels[i] != PIOS_RCVR_TIMEOUT)) valid_input_detected = true; } diff --git a/flight/pios/pios.h b/flight/pios/pios.h index 5e581b345..f1e7e7f4a 100644 --- a/flight/pios/pios.h +++ b/flight/pios/pios.h @@ -65,6 +65,7 @@ /* PIOS debug interface */ /* #define PIOS_INCLUDE_DEBUG_CONSOLE */ /* #define DEBUG_LEVEL 0 */ +/* #define PIOS_ENABLE_DEBUG_PINS */ #include /* PIOS common functions */ diff --git a/flight/pios/stm32f10x/pios_debug.c b/flight/pios/stm32f10x/pios_debug.c index f7c9d6cf3..e7e7e148e 100644 --- a/flight/pios/stm32f10x/pios_debug.c +++ b/flight/pios/stm32f10x/pios_debug.c @@ -7,7 +7,7 @@ * @{ * * @file pios_debug.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013. * @brief Debugging Functions * @see The GNU Public License (GPL) Version 3 * @@ -60,13 +60,13 @@ void PIOS_DEBUG_Init(const struct pios_tim_channel * channels, uint8_t num_chann GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Pin = chan->init->GPIO_Pin; + GPIO_InitStructure.GPIO_Pin = chan->pin.init.GPIO_Pin; /* Initialize the GPIO */ - GPIO_Init(chan->init->port, &GPIO_InitStructure); + GPIO_Init(chan->pin.gpio, &GPIO_InitStructure); /* Set the pin low */ - GPIO_WriteBit(chan->init->port, chan->init->GPIO_Pin, Bit_RESET); + GPIO_WriteBit(chan->pin.gpio, chan->pin.init.GPIO_Pin, Bit_RESET); } #endif // PIOS_ENABLE_DEBUG_PINS } @@ -84,7 +84,7 @@ void PIOS_DEBUG_PinHigh(uint8_t pin) const struct pios_tim_channel * chan = &debug_channels[pin]; - GPIO_WriteBit(chan->init->port, chan->init->GPIO_Pin, Bit_Set); + GPIO_WriteBit(chan->pin.gpio, chan->pin.init.GPIO_Pin, Bit_SET); #endif // PIOS_ENABLE_DEBUG_PINS } @@ -102,7 +102,7 @@ void PIOS_DEBUG_PinLow(uint8_t pin) const struct pios_tim_channel * chan = &debug_channels[pin]; - GPIO_WriteBit(chan->init->port, chan->init->GPIO_Pin, Bit_RESET); + GPIO_WriteBit(chan->pin.gpio, chan->pin.init.GPIO_Pin, Bit_RESET); #endif // PIOS_ENABLE_DEBUG_PINS } @@ -124,8 +124,8 @@ void PIOS_DEBUG_PinValue8Bit(uint8_t value) * This is sketchy since it assumes a particular ordering * and bitwise layout of the channels provided to the debug code. */ - debug_channels[0].init.port->BSRR = bsrr_l; - debug_channels[4].init.port->BSRR = bsrr_h; + debug_channels[0].pin.gpio->BSRR = bsrr_l; + debug_channels[4].pin.gpio->BSRR = bsrr_h; PIOS_IRQ_Enable(); #endif // PIOS_ENABLE_DEBUG_PINS @@ -143,7 +143,7 @@ void PIOS_DEBUG_PinValue4BitL(uint8_t value) * and bitwise layout of the channels provided to the debug code. */ uint32_t bsrr_l = ((~(value & 0x0F)<<(16+6))) | ((value & 0x0F)<<6); - debug_channels[0].init.port->BSRR = bsrr_l; + debug_channels[0].pin.gpio->BSRR = bsrr_l; #endif // PIOS_ENABLE_DEBUG_PINS } diff --git a/flight/pios/stm32f10x/pios_ppm.c b/flight/pios/stm32f10x/pios_ppm.c index 63e73fe39..f9d825162 100644 --- a/flight/pios/stm32f10x/pios_ppm.c +++ b/flight/pios/stm32f10x/pios_ppm.c @@ -188,6 +188,7 @@ extern int32_t PIOS_PPM_Init(uint32_t * ppm_id, const struct pios_ppm_cfg * cfg) TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; + ppm_dev->supv_timer = 0; if (!PIOS_RTC_RegisterTickCallback(PIOS_PPM_Supervisor, (uint32_t)ppm_dev)) { PIOS_DEBUG_Assert(0); } diff --git a/flight/pios/stm32f10x/pios_ppm_out.c b/flight/pios/stm32f10x/pios_ppm_out.c index 6dd8c7915..72dbf3056 100644 --- a/flight/pios/stm32f10x/pios_ppm_out.c +++ b/flight/pios/stm32f10x/pios_ppm_out.c @@ -49,16 +49,20 @@ struct pios_ppm_out_dev { enum pios_ppm_out_dev_magic magic; const struct pios_ppm_out_cfg * cfg; - uint32_t triggering_period; + uint32_t TriggeringPeriod; uint32_t ChannelSum; uint8_t NumChannelCounter; uint16_t ChannelValue[PIOS_PPM_OUT_MAX_CHANNELS]; - uint8_t supv_timer; - bool Tracking; + uint8_t SupvTimer; bool Fresh; + bool Tracking; + bool Enabled; }; +static void PIOS_PPM_Out_Supervisor(uint32_t ppm_id); +static void PIOS_PPM_Out_Enable_Disable(struct pios_ppm_out_dev *ppm_dev, bool enable); + static bool PIOS_PPM_Out_validate(struct pios_ppm_out_dev *ppm_dev) { return (ppm_dev->magic == PIOS_PPM_OUT_DEV_MAGIC); @@ -115,12 +119,12 @@ int32_t PIOS_PPM_Out_Init(uint32_t *ppm_out_id, const struct pios_ppm_out_cfg * ppm_dev->cfg = cfg; // Set up the state variables - ppm_dev->triggering_period = PIOS_PPM_OUT_HIGH_PULSE_US; + ppm_dev->TriggeringPeriod = PIOS_PPM_OUT_HIGH_PULSE_US; ppm_dev->ChannelSum = 0; ppm_dev->NumChannelCounter = 0; // Flush counter variables - for (uint8_t i = 0; i < PIOS_PPM_OUT_MAX_CHANNELS; i++) + for (uint8_t i = 0; i < PIOS_PPM_OUT_MAX_CHANNELS; ++i) ppm_dev->ChannelValue[i] = 1000; uint32_t tim_id; @@ -149,20 +153,6 @@ int32_t PIOS_PPM_Out_Init(uint32_t *ppm_out_id, const struct pios_ppm_out_cfg * TIM_OC4PreloadConfig(chan->timer, TIM_OCPreload_Enable); break; } - switch (chan->timer_chan) { - case TIM_Channel_1: - TIM_ITConfig(chan->timer, TIM_IT_CC1 | TIM_IT_Update, ENABLE); - break; - case TIM_Channel_2: - TIM_ITConfig(chan->timer, TIM_IT_CC2 | TIM_IT_Update, ENABLE); - break; - case TIM_Channel_3: - TIM_ITConfig(chan->timer, TIM_IT_CC3 | TIM_IT_Update, ENABLE); - break; - case TIM_Channel_4: - TIM_ITConfig(chan->timer, TIM_IT_CC4 | TIM_IT_Update, ENABLE); - break; - } TIM_ARRPreloadConfig(chan->timer, ENABLE); TIM_CtrlPWMOutputs(chan->timer, ENABLE); @@ -174,20 +164,17 @@ int32_t PIOS_PPM_Out_Init(uint32_t *ppm_out_id, const struct pios_ppm_out_cfg * TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1; TIM_TimeBaseStructure.TIM_Period = ((1000000 / 100) - 1); TIM_TimeBaseInit(chan->timer, &TIM_TimeBaseStructure); - switch(chan->timer_chan) { - case TIM_Channel_1: - TIM_SetCompare1(chan->timer, ppm_dev->triggering_period); - break; - case TIM_Channel_2: - TIM_SetCompare2(chan->timer, ppm_dev->triggering_period); - break; - case TIM_Channel_3: - TIM_SetCompare3(chan->timer, ppm_dev->triggering_period); - break; - case TIM_Channel_4: - TIM_SetCompare4(chan->timer, ppm_dev->triggering_period); - break; + PIOS_PPM_Out_Enable_Disable(ppm_dev, false); + + // Configure the supervisor + ppm_dev->SupvTimer = 0; + ppm_dev->Fresh = FALSE; + ppm_dev->Tracking = FALSE; + ppm_dev->Enabled = FALSE; + if (!PIOS_RTC_RegisterTickCallback(PIOS_PPM_Out_Supervisor, (uint32_t)ppm_dev)) { + PIOS_DEBUG_Assert(0); } + return 0; } @@ -202,6 +189,15 @@ void PIOS_PPM_OUT_Set(uint32_t ppm_out_id, uint8_t servo, uint16_t position) position = PIOS_PPM_OUT_MIN_CHANNEL_PULSE_US; if (position > PIOS_PPM_OUT_MAX_CHANNEL_PULSE_US) position = PIOS_PPM_OUT_MAX_CHANNEL_PULSE_US; + + // Update the supervisor tracking variables. + ppm_dev->Fresh = TRUE; + + // Reenable the TIM if it's been turned off. + if (!ppm_dev->Tracking) { + ppm_dev->Tracking = TRUE; + PIOS_PPM_Out_Enable_Disable(ppm_dev, true); + } // Update the position ppm_dev->ChannelValue[servo] = position; @@ -213,13 +209,29 @@ static void PIOS_PPM_OUT_tim_edge_cb (uint32_t tim_id, uint32_t context, uint8_t if (!PIOS_PPM_Out_validate(ppm_dev)) return; + // Just return if the device is disabled. + if (!ppm_dev->Enabled) { + return; + } + + // Turn off the PPM stream if we are no longer receiving update + // Note: This must happen between frames. + if ((ppm_dev->NumChannelCounter == 0) && !ppm_dev->Tracking) { + // Flush counter variables + for (uint8_t i = 0; i < PIOS_PPM_OUT_MAX_CHANNELS; ++i) { + ppm_dev->ChannelValue[i] = 1000; + } + PIOS_PPM_Out_Enable_Disable(ppm_dev, false); + return; + } + // Finish out the frame if we reached the last channel. uint32_t pulse_width; if ((ppm_dev->NumChannelCounter >= PIOS_PPM_OUT_MAX_CHANNELS)) { pulse_width = PIOS_PPM_OUT_FRAME_PERIOD_US - ppm_dev->ChannelSum; ppm_dev->NumChannelCounter = 0; ppm_dev->ChannelSum = 0; - } else + } else ppm_dev->ChannelSum += (pulse_width = ppm_dev->ChannelValue[ppm_dev->NumChannelCounter++]); // Initiate the pulse @@ -228,4 +240,50 @@ static void PIOS_PPM_OUT_tim_edge_cb (uint32_t tim_id, uint32_t context, uint8_t return; } +static void PIOS_PPM_Out_Enable_Disable(struct pios_ppm_out_dev *ppm_dev, bool enable) +{ + const struct pios_tim_channel *chan = ppm_dev->cfg->channel; + uint32_t trig = enable ? ppm_dev->TriggeringPeriod : 0; + FunctionalState state = enable ? ENABLE : DISABLE; + ppm_dev->Enabled = enable; + switch (chan->timer_chan) { + case TIM_Channel_1: + TIM_ITConfig(chan->timer, TIM_IT_CC1 | TIM_IT_Update, state); + TIM_SetCompare1(chan->timer, trig); + break; + case TIM_Channel_2: + TIM_ITConfig(chan->timer, TIM_IT_CC2 | TIM_IT_Update, state); + TIM_SetCompare2(chan->timer, trig); + break; + case TIM_Channel_3: + TIM_ITConfig(chan->timer, TIM_IT_CC3 | TIM_IT_Update, state); + TIM_SetCompare3(chan->timer, trig); + break; + case TIM_Channel_4: + TIM_ITConfig(chan->timer, TIM_IT_CC4 | TIM_IT_Update, state); + TIM_SetCompare4(chan->timer, trig); + break; + } +} + +static void PIOS_PPM_Out_Supervisor(uint32_t ppm_out_id) { + struct pios_ppm_out_dev *ppm_dev = (struct pios_ppm_out_dev *)ppm_out_id; + if (!PIOS_PPM_Out_validate(ppm_dev)) + return; + + // RTC runs at 625Hz so divide down the base rate so that this loop runs at 12.5Hz. + if(++(ppm_dev->SupvTimer) < 50) { + return; + } + ppm_dev->SupvTimer = 0; + + // Go into failsafe the channel values haven't been refreshed since the last time through. + if (!ppm_dev->Fresh) { + ppm_dev->Tracking = FALSE; + } + + // Set Fresh to false to test if channel values are being refreshed. + ppm_dev->Fresh = FALSE; +} + #endif /* PIOS_INCLUDE_PPM_OUT */ diff --git a/flight/pios/stm32f4xx/pios_debug.c b/flight/pios/stm32f4xx/pios_debug.c index 51efbc188..8fe050b07 100644 --- a/flight/pios/stm32f4xx/pios_debug.c +++ b/flight/pios/stm32f4xx/pios_debug.c @@ -7,7 +7,7 @@ * @{ * * @file pios_debug.c - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013. * @brief Debugging Functions * @see The GNU Public License (GPL) Version 3 * @@ -58,15 +58,17 @@ void PIOS_DEBUG_Init(const struct pios_tim_channel * channels, uint8_t num_chann // Initialise pins as standard output pins GPIO_InitTypeDef GPIO_InitStructure; GPIO_StructInit(&GPIO_InitStructure); - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Pin = chan->init->GPIO_Pin; + GPIO_InitStructure.GPIO_Pin = chan->pin.init.GPIO_Pin; /* Initialize the GPIO */ - GPIO_Init(chan->init->port, &GPIO_InitStructure); + GPIO_Init(chan->pin.gpio, &GPIO_InitStructure); /* Set the pin low */ - GPIO_WriteBit(chan->init->port, chan->init->GPIO_Pin, Bit_RESET); + GPIO_WriteBit(chan->pin.gpio, chan->pin.init.GPIO_Pin, Bit_RESET); } #endif // PIOS_ENABLE_DEBUG_PINS } @@ -84,7 +86,7 @@ void PIOS_DEBUG_PinHigh(uint8_t pin) const struct pios_tim_channel * chan = &debug_channels[pin]; - GPIO_WriteBit(chan->init->port, chan->init->GPIO_Pin, Bit_Set); + GPIO_WriteBit(chan->pin.gpio, chan->pin.init.GPIO_Pin, Bit_SET); #endif // PIOS_ENABLE_DEBUG_PINS } @@ -102,7 +104,7 @@ void PIOS_DEBUG_PinLow(uint8_t pin) const struct pios_tim_channel * chan = &debug_channels[pin]; - GPIO_WriteBit(chan->init->port, chan->init->GPIO_Pin, Bit_RESET); + GPIO_WriteBit(chan->pin.gpio, chan->pin.init.GPIO_Pin, Bit_RESET); #endif // PIOS_ENABLE_DEBUG_PINS } @@ -115,6 +117,9 @@ void PIOS_DEBUG_PinValue8Bit(uint8_t value) return; } +#pragma message("This code is not portable and should be revised") + PIOS_Assert(0); + uint32_t bsrr_l = ( ((~value)&0x0F)<<(16+6) ) | ((value & 0x0F)<<6); uint32_t bsrr_h = ( ((~value)&0xF0)<<(16+6-4) ) | ((value & 0xF0)<<(6-4)); @@ -124,8 +129,8 @@ void PIOS_DEBUG_PinValue8Bit(uint8_t value) * This is sketchy since it assumes a particular ordering * and bitwise layout of the channels provided to the debug code. */ - debug_channels[0].init.port->BSRR = bsrr_l; - debug_channels[4].init.port->BSRR = bsrr_h; + //debug_channels[0].pin.gpio->BSRR = bsrr_l; + //debug_channels[4].pin.gpio->BSRR = bsrr_h; PIOS_IRQ_Enable(); #endif // PIOS_ENABLE_DEBUG_PINS @@ -138,12 +143,15 @@ void PIOS_DEBUG_PinValue4BitL(uint8_t value) return; } +#pragma message("This code is not portable and should be revised") + PIOS_Assert(0); + /* * This is sketchy since it assumes a particular ordering * and bitwise layout of the channels provided to the debug code. */ uint32_t bsrr_l = ((~(value & 0x0F)<<(16+6))) | ((value & 0x0F)<<6); - debug_channels[0].init.port->BSRR = bsrr_l; + //debug_channels[0].pin.gpio->BSRR = bsrr_l; #endif // PIOS_ENABLE_DEBUG_PINS } diff --git a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h index ea4f2ae1d..207920f98 100644 --- a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h +++ b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h @@ -38,6 +38,7 @@ /* #define PIOS_INCLUDE_DEBUG_CONSOLE */ /* #define DEBUG_LEVEL 0 */ +/* #define PIOS_ENABLE_DEBUG_PINS */ /* PIOS FreeRTOS support */ #define PIOS_INCLUDE_FREERTOS diff --git a/flight/targets/boards/coptercontrol/firmware/pios_board.c b/flight/targets/boards/coptercontrol/firmware/pios_board.c index d620acfee..12b38640d 100644 --- a/flight/targets/boards/coptercontrol/firmware/pios_board.c +++ b/flight/targets/boards/coptercontrol/firmware/pios_board.c @@ -773,7 +773,7 @@ void PIOS_Board_Init(void) { /* Remap AFIO pin for PB4 (Servo 5 Out)*/ GPIO_PinRemapConfig( GPIO_Remap_SWJ_NoJTRST, ENABLE); -#ifndef PIOS_DEBUG_ENABLE_DEBUG_PINS +#ifndef PIOS_ENABLE_DEBUG_PINS switch (hwsettings_rcvrport) { case HWSETTINGS_CC_RCVRPORT_DISABLED: case HWSETTINGS_CC_RCVRPORT_PWM: @@ -787,8 +787,8 @@ void PIOS_Board_Init(void) { break; } #else - PIOS_DEBUG_Init(&pios_tim_servo_all_channels, NELEMENTS(pios_tim_servo_all_channels)); -#endif /* PIOS_DEBUG_ENABLE_DEBUG_PINS */ + PIOS_DEBUG_Init(pios_tim_servoport_all_pins, NELEMENTS(pios_tim_servoport_all_pins)); +#endif /* PIOS_ENABLE_DEBUG_PINS */ switch(bdinfo->board_rev) { case BOARD_REVISION_CC: diff --git a/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h b/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h index 1da5edbe0..6d149e4f1 100644 --- a/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h +++ b/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h @@ -38,6 +38,7 @@ /* #define PIOS_INCLUDE_DEBUG_CONSOLE */ /* #define DEBUG_LEVEL 0 */ +/* #define PIOS_ENABLE_DEBUG_PINS */ /* PIOS FreeRTOS support */ #define PIOS_INCLUDE_FREERTOS diff --git a/flight/targets/boards/osd/firmware/inc/pios_config.h b/flight/targets/boards/osd/firmware/inc/pios_config.h index c08dda8b5..3772c5939 100644 --- a/flight/targets/boards/osd/firmware/inc/pios_config.h +++ b/flight/targets/boards/osd/firmware/inc/pios_config.h @@ -38,6 +38,7 @@ /* #define PIOS_INCLUDE_DEBUG_CONSOLE */ /* #define DEBUG_LEVEL 0 */ +/* #define PIOS_ENABLE_DEBUG_PINS */ /* PIOS FreeRTOS support */ #define PIOS_INCLUDE_FREERTOS diff --git a/flight/targets/boards/revolution/firmware/inc/pios_config.h b/flight/targets/boards/revolution/firmware/inc/pios_config.h index 1df7180b3..1025db7e3 100644 --- a/flight/targets/boards/revolution/firmware/inc/pios_config.h +++ b/flight/targets/boards/revolution/firmware/inc/pios_config.h @@ -38,6 +38,7 @@ /* #define PIOS_INCLUDE_DEBUG_CONSOLE */ /* #define DEBUG_LEVEL 0 */ +/* #define PIOS_ENABLE_DEBUG_PINS */ /* PIOS FreeRTOS support */ #define PIOS_INCLUDE_FREERTOS diff --git a/flight/targets/boards/revolution/firmware/pios_board.c b/flight/targets/boards/revolution/firmware/pios_board.c index 5263da346..559ab4a81 100644 --- a/flight/targets/boards/revolution/firmware/pios_board.c +++ b/flight/targets/boards/revolution/firmware/pios_board.c @@ -777,11 +777,11 @@ void PIOS_Board_Init(void) { pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_GCS] = pios_gcsrcvr_rcvr_id; #endif /* PIOS_INCLUDE_GCSRCVR */ -#ifndef PIOS_DEBUG_ENABLE_DEBUG_PINS +#ifndef PIOS_ENABLE_DEBUG_PINS // pios_servo_cfg points to the correct configuration based on input port settings PIOS_Servo_Init(pios_servo_cfg); #else - PIOS_DEBUG_Init(&pios_tim_servo_all_channels, NELEMENTS(pios_tim_servo_all_channels)); + PIOS_DEBUG_Init(pios_tim_servoport_all_pins, NELEMENTS(pios_tim_servoport_all_pins)); #endif if (PIOS_I2C_Init(&pios_i2c_mag_pressure_adapter_id, &pios_i2c_mag_pressure_adapter_cfg)) { diff --git a/flight/targets/boards/revoproto/firmware/inc/pios_config.h b/flight/targets/boards/revoproto/firmware/inc/pios_config.h index c148d9142..2e428bd01 100644 --- a/flight/targets/boards/revoproto/firmware/inc/pios_config.h +++ b/flight/targets/boards/revoproto/firmware/inc/pios_config.h @@ -38,6 +38,7 @@ /* #define PIOS_INCLUDE_DEBUG_CONSOLE */ /* #define DEBUG_LEVEL 0 */ +/* #define PIOS_ENABLE_DEBUG_PINS */ /* PIOS FreeRTOS support */ #define PIOS_INCLUDE_FREERTOS diff --git a/flight/targets/boards/revoproto/firmware/pios_board.c b/flight/targets/boards/revoproto/firmware/pios_board.c index d4b390b72..8a0679a5b 100644 --- a/flight/targets/boards/revoproto/firmware/pios_board.c +++ b/flight/targets/boards/revoproto/firmware/pios_board.c @@ -826,7 +826,7 @@ void PIOS_Board_Init(void) { pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_GCS] = pios_gcsrcvr_rcvr_id; #endif /* PIOS_INCLUDE_GCSRCVR */ -#ifndef PIOS_DEBUG_ENABLE_DEBUG_PINS +#ifndef PIOS_ENABLE_DEBUG_PINS switch (hwsettings_rcvrport) { case HWSETTINGS_RV_RCVRPORT_DISABLED: case HWSETTINGS_RV_RCVRPORT_PWM: @@ -842,7 +842,7 @@ void PIOS_Board_Init(void) { break; } #else - PIOS_DEBUG_Init(&pios_tim_servo_all_channels, NELEMENTS(pios_tim_servo_all_channels)); + PIOS_DEBUG_Init(pios_tim_servoport_all_pins, NELEMENTS(pios_tim_servoport_all_pins)); #endif if (PIOS_I2C_Init(&pios_i2c_mag_adapter_id, &pios_i2c_mag_adapter_cfg)) { diff --git a/ground/openpilotgcs/src/plugins/config/airframe.ui b/ground/openpilotgcs/src/plugins/config/airframe.ui index e70184c17..da2f1898c 100644 --- a/ground/openpilotgcs/src/plugins/config/airframe.ui +++ b/ground/openpilotgcs/src/plugins/config/airframe.ui @@ -17,27 +17,96 @@ 12 + + + + + 0 + 0 + + + + + + + + 9 + + + + + + 0 + 0 + + + + + 75 + true + + + + Vehicle type: + + + + + + + + 0 + 0 + + + + + 50 + false + + + + Select aircraft type here + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 2 + 20 + + + + + + + 0 - + true Mixer Settings - - - 0 - + - 0 + 9 - - + + 0 @@ -128,75 +197,14 @@ 0 0 - 852 - 518 + 832 + 461 - 12 + 0 - - - - - - - - 12 - - - - - QLayout::SetFixedSize - - - - - - 0 - 0 - - - - - 75 - true - - - - Vehicle type: - - - - - - - Select aircraft type here - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 2 - 20 - - - - - - - - - @@ -215,2639 +223,8 @@ QFrame::NoFrame - 4 + -1 - - - true - - - false - - - - - - - - - - - 0 - 0 - - - - - 75 - true - - - - Airplane type: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - 0 - 0 - - - - - 230 - 100 - - - - Output Channel Assignments - - - - - - Engine - - - - - - - Select output channel for the engine - - - - - - - - 60 - 0 - - - - Aileron 1 - - - - - - - Select output channel for the first aileron (or elevon) - - - - - - - false - - - - 60 - 0 - - - - Aileron 2 - - - - - - - false - - - Select output channel for the second aileron (or elevon) - - - - - - - - 67 - 0 - - - - Elevator 1 - - - - - - - Select output channel for the first elevator - - - - - - - false - - - - 67 - 0 - - - - Elevator 2 - - - - - - - false - - - Select output channel for a secondary elevator - - - - - - - Rudder 1 - - - - - - - Select output channel for the first rudder - - - - - - - Rudder 2 - - - - - - - Select output channel for a secondary rudder - - - - - - - Qt::Vertical - - - - 20 - 20 - - - - - - - - - - - - 0 - 0 - - - - Elevon Mix - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 20 - - - - - - - - - - - - - 65 - 0 - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - Rudder % - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - 100 - - - 50 - - - Qt::Vertical - - - - - - - 50 - - - Qt::AlignCenter - - - - - - - - - - - - 50 - 0 - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - Pitch % - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - 100 - - - 50 - - - Qt::Vertical - - - - - - - 50 - - - Qt::AlignCenter - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 100 - - - - Throttle Curve - - - - - - - 1 - 1 - - - - - 0 - 0 - - - - - 500 - 500 - - - - - 10 - 10 - - - - - 300 - 350 - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 75 - true - - - - Mixer OK - - - - - - - - - - - - - 0 - - - 6 - - - - - - 10 - 10 - - - - - 16777215 - 16777215 - - - - Frame Type - - - - 12 - - - - - QLayout::SetFixedSize - - - - - Qt::Horizontal - - - - 10 - 13 - - - - - - - - - 0 - 0 - - - - - 25 - 25 - - - - - 16777215 - 25 - - - - Select the Multirotor frame type here. - - - - - - - Qt::Horizontal - - - - 10 - 13 - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 8 - - - - - - - - - 0 - 0 - - - - - 10 - 10 - - - - background:transparent - - - QFrame::NoFrame - - - QFrame::Plain - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 8 - - - - - - - - - - - - 0 - 0 - - - - - 10 - 10 - - - - - 16777215 - 16777215 - - - - Throttle Curve - - - - 12 - - - - - - 0 - 0 - - - - - 10 - 10 - - - - - 10 - 10 - - - - - 50 - 50 - - - - background:transparent - - - - - - - - - - - 16777215 - 16777215 - - - - Mix Level - - - - 0 - - - 12 - - - - - - - - 30 - 0 - - - - 100 - - - Qt::AlignCenter - - - - - - - - 35 - 0 - - - - Weight of Roll mixing in percent. -Typical values are 100% for + configuration and 50% for X configuration on quads. - - - 100 - - - 100 - - - Qt::Vertical - - - - - - - - 0 - 0 - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - Roll - - - Qt::AlignCenter - - - - - - - - - - - - 0 - 0 - - - - 100 - - - Qt::AlignCenter - - - - - - - - 35 - 0 - - - - Weight of Pitch mixing in percent. -Typical values are 100% for + configuration and 50% for X configuration on quads. - - - 100 - - - 100 - - - Qt::Vertical - - - - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - Pitch - - - Qt::AlignCenter - - - - - - - - - - - - 0 - 0 - - - - 50 - - - Qt::AlignCenter - - - - - - - - 40 - 0 - - - - Weight of Yaw mixing in percent. -Typical value is 50% for + or X configuration on quads. - - - 0 - - - 100 - - - 50 - - - Qt::Vertical - - - - - - - false - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - Yaw - - - Qt::AlignCenter - - - - - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - - 0 - 0 - - - - - 75 - true - - - - Mixer OK - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 140 - - - - Motor output channels - - - - 12 - - - - - QLayout::SetMaximumSize - - - QFormLayout::AllNonFixedFieldsGrow - - - 6 - - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - 1 - - - - - - - Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. - - - - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - 2 - - - - - - - Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. - - - - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - 3 - - - - - - - Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. - - - - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - 4 - - - - - - - Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. - - - - - - - - - QLayout::SetMaximumSize - - - QFormLayout::AllNonFixedFieldsGrow - - - 6 - - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - 5 - - - - - - - false - - - - 0 - 0 - - - - Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. - - - - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - 6 - - - - - - - false - - - Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. - - - - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - 7 - - - - - - - false - - - Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. - - - - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - 8 - - - - - - - false - - - Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. - - - - - - - - - - 0 - 0 - - - - Qt::Vertical - - - - - - - - 0 - 0 - - - - - 0 - 16 - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - Multirotor Motor Direction - - - Qt::AlignCenter - - - - - - - false - - - - 0 - 0 - - - - - 40 - 0 - - - - - - - - - 0 - 0 - - - - - 0 - 16 - - - - background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); -color: rgb(255, 255, 255); -border-radius: 5; -font: bold 12px; -margin:1px; - - - Tricopter Yaw Servo channel - - - Qt::AlignCenter - - - - - - - Reverse all motors - - - - - - - - - - - - 0 - - - 0 - - - - - 0 - - - - - - - - - - - true - - - false - - - - - - true - - - - - 0 - 0 - 808 - 397 - - - - - - - - - - - - 0 - 0 - - - - - 75 - true - - - - Vehicle type: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 75 - true - - - - Channel Assignment - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 100 - - - - Output channel asignmets - - - - - - - 77 - 0 - - - - Engine - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Select output channel for the engine - - - - - - - - 60 - 0 - - - - Aileron 1 - - - - - - - Select output channel for the first aileron (or elevon) - - - - - - - false - - - - 60 - 0 - - - - Aileron 2 - - - - - - - false - - - Select output channel for the second aileron (or elevon) - - - - - - - - 0 - 0 - - - - Motor - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Select output channel for the first motor - - - - - - - false - - - - 47 - 0 - - - - Motor 2 - - - - - - - false - - - Select output channel for a second motor - - - - - - - Front Steering - - - - - - - Select output channel for the first steering actuator - - - - - - - Rear Steering - - - - - - - Select output channel for a second steering actuator - - - - - - - - - - true - - - - 0 - 0 - - - - Differential Steering Mix - - - - - - - - - - - 65 - 0 - - - - Left % - - - - - - - 100 - - - 50 - - - Qt::Vertical - - - - - - - 50 - - - - - - - - - - - - 50 - 0 - - - - Right % - - - - - - - 100 - - - 50 - - - Qt::Vertical - - - - - - - 50 - - - - - - - - - - - - - - - 0 - 100 - - - - Front throttle curve - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 500 - 500 - - - - - 10 - 10 - - - - - 300 - 350 - - - - - - - - - - - - 0 - 0 - - - - Rear throttle curve - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 500 - 500 - - - - - 10 - 10 - - - - - 300 - 350 - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 75 - true - - - - Mixer OK - - - - - - - - - - - - - - - - - - - - - - - - 0 - 0 - - - - Curve 1 - - - - - - - 1 - 1 - - - - - 50 - 50 - - - - - 1000 - 1000 - - - - - 10 - 10 - - - - - 300 - 350 - - - - - - - - - - - Curve 2 - - - - - - - 1 - 1 - - - - - 50 - 50 - - - - - 1000 - 1000 - - - - - 10 - 10 - - - - - 300 - 350 - - - - - - - - - - - - - - 0 - 0 - - - - true - - - 12 - - - 50 - - - false - - - - Type - - - - - Curve 1 - - - - - Curve 2 - - - - - Roll - - - - - Pitch - - - - - Yaw - - - - - Ch 1 - - - - - Ch 2 - - - - - Ch 3 - - - - - Ch 4 - - - - - Ch 5 - - - - - Ch 6 - - - - - Ch 7 - - - - - Ch 8 - - - - - Ch 9 - - - - - Ch 10 - - - - - Ch 11 - - - - - Ch 12 - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - AlignHCenter|AlignVCenter|AlignCenter - - - - - - - - - @@ -2856,7 +233,7 @@ margin:1px; - + true @@ -2950,8 +327,8 @@ margin:1px; 0 0 - 852 - 518 + 223 + 269 @@ -3334,13 +711,14 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Ubuntu'; font-size:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> <tr> <td style="border: none;"> -<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; font-weight:600; color:#ff0000;">SETTING UP FEED FORWARD REQUIRES CAUTION</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;"><br /></span></p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:14pt; font-weight:600; color:#ff0000;">SETTING UP FEED FORWARD REQUIRES CAUTION</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;"><br /></span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;"><br /></span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:13pt;">Beware: Feed Forward Tuning will launch all engines around mid-throttle, you have been warned!</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:13pt;">Remove your props initially, and for fine-tuning, make sure your airframe is safely held in place. Wear glasses and protect your face and body.</span></p></td></tr></table></body></html> @@ -3355,7 +733,7 @@ p, li { white-space: pre-wrap; } - + 4 @@ -3431,20 +809,6 @@ p, li { white-space: pre-wrap; } - - - MixerCurve - QWidget -
mixercurve.h
- 1 -
- - ConfigCcpmWidget - QWidget -
cfg_vehicletypes/configccpmwidget.h
- 1 -
-
@@ -3481,117 +845,5 @@ p, li { white-space: pre-wrap; } - - elevonSlider1 - valueChanged(int) - elevonSliderLabel1 - setNum(int) - - - 124 - 126 - - - 124 - 126 - - - - - elevonSlider2 - valueChanged(int) - elevonSliderLabel2 - setNum(int) - - - 362 - 299 - - - 124 - 126 - - - - - differentialSteeringSlider1 - valueChanged(int) - gvDiffSteering1Label - setNum(int) - - - 124 - 126 - - - 315 - 391 - - - - - differentialSteeringSlider2 - valueChanged(int) - gvDiffSteering2Label - setNum(int) - - - 124 - 126 - - - 390 - 391 - - - - - mrRollMixLevel - valueChanged(int) - mrRollMixValue - setNum(int) - - - 42 - 220 - - - 43 - 171 - - - - - mrYawMixLevel - valueChanged(int) - mrYawMixValue - setNum(int) - - - 120 - 254 - - - 121 - 172 - - - - - mrPitchMixLevel - valueChanged(int) - mrPitchMixValue - setNum(int) - - - 92 - 222 - - - 92 - 151 - - - diff --git a/ground/openpilotgcs/src/plugins/config/airframe_ccpm.ui b/ground/openpilotgcs/src/plugins/config/airframe_ccpm.ui new file mode 100644 index 000000000..c9942dc3a --- /dev/null +++ b/ground/openpilotgcs/src/plugins/config/airframe_ccpm.ui @@ -0,0 +1,3391 @@ + + + CcpmConfigWidget + + + + 0 + 0 + 850 + 572 + + + + + 0 + 0 + + + + + 300 + 300 + + + + Form + + + false + + + + 0 + + + + + + + 0 + + + + + + 75 + true + + + + Swashplate config: + + + + + + + Select aircraft type here + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 0 + + + + + 300 + 300 + + + + #SwashplateBox,#SwashplateBox_2,#SwashplateBox_3,#SwashplateBox_4,#ccpmSwashImageBox,#SwashLvlInstructionsBox,#SwashLvlccpmSwashImageBox,#SwashLvlccpmSliderBox,#SwashLvlStatusBox,#ThrottleCurveBox,#PitchCurveBox{ +background-color: qlineargradient(spread:pad, x1:0.507, y1:0.869318, x2:0.507, y2:0.0965909, stop:0 rgba(243, 243, 243, 255), stop:1 rgba(250, 250, 250, 255)); +border: 1px outset #999; +border-radius: 3; +font:bold; +} + +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top center; /* position at the top center */ + padding: 0 3px; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #FFOECE, stop: 1 #FFFFFF); + top: 5px; + } + + + QTabWidget::Rounded + + + 0 + + + false + + + + Basic settings + + + + 9 + + + 6 + + + + + + + + 0 + 0 + + + + + 190 + 16777215 + + + + Motor outputs + + + + 3 + + + 2 + + + 3 + + + + + + 0 + 0 + + + + + 85 + 0 + + + + + 100 + 16777215 + + + + + + + + + 0 + 0 + + + + + 85 + 0 + + + + + 100 + 16777215 + + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Tail Rotor + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Engine + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + + + 0 + 0 + + + + + 190 + 16777215 + + + + Swashplate outputs + + + + 3 + + + 2 + + + 3 + + + + + true + + + + 1 + 1 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Servo W + + + + + + + true + + + + 0 + 0 + + + + + 85 + 0 + + + + + 100 + 16777215 + + + + + + + + + 0 + 0 + + + + + 85 + 0 + + + + + 100 + 16777215 + + + + + + + + true + + + + 0 + 0 + + + + + 85 + 0 + + + + + 100 + 16777215 + + + + + + + + + 1 + 1 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Servo X + + + + + + + + 0 + 0 + + + + + 85 + 0 + + + + + 100 + 16777215 + + + + + Front + + + + + Right + + + + + Rear + + + + + Left + + + + + + + + + 1 + 1 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + 1st Servo + + + + + + + + 0 + 0 + + + + + 85 + 0 + + + + + 100 + 16777215 + + + + + + + + + 1 + 1 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Servo Z + + + + + + + true + + + + 1 + 1 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Servo Y + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + + + 0 + 0 + + + + + 70 + 0 + + + + + 190 + 16777215 + + + + Swashplate Servo Angles + + + + 3 + + + 2 + + + 3 + + + + + + 0 + 0 + + + + + 85 + 0 + + + + + 85 + 16777215 + + + + 0 + + + 360.000000000000000 + + + 15.000000000000000 + + + + + + + true + + + + 0 + 0 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Angle W + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Angle X + + + + + + + true + + + + 0 + 0 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Angle Y + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Angle Z + + + + + + + true + + + + 0 + 0 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Correction Angle + + + true + + + + + + + + 0 + 0 + + + + + 85 + 0 + + + + + 85 + 16777215 + + + + 0 + + + 360.000000000000000 + + + 15.000000000000000 + + + + + + + true + + + + 0 + 0 + + + + + 85 + 0 + + + + + 85 + 16777215 + + + + 0 + + + 360.000000000000000 + + + 15.000000000000000 + + + + + + + + 0 + 0 + + + + + 85 + 0 + + + + + 85 + 16777215 + + + + 0 + + + 360.000000000000000 + + + 15.000000000000000 + + + + + + + + 0 + 0 + + + + + 85 + 0 + + + + + 85 + 16777215 + + + + 0 + + + 360.000000000000000 + + + 15.000000000000000 + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + + + 0 + 0 + + + + + 190 + 16777215 + + + + CCPM Options + + + + 3 + + + 2 + + + 3 + + + + + Collective Pass through + + + + + + + Link Roll/Pitch + + + true + + + + + + + Link Cyclic/Collective + + + true + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 0 + + + 0 + + + + + + 1 + 1 + + + + + 200 + 200 + + + + + 600 + 600 + + + + + 10 + 10 + + + + + 200 + 200 + + + + + 75 + false + true + + + + Swashplate Layout + + + Qt::AlignHCenter|Qt::AlignTop + + + false + + + false + + + + 3 + + + 3 + + + + + Qt::Vertical + + + + + 1 + 1 + + + + + 10 + 10 + + + + + 1000 + 1000 + + + + + 10 + 10 + + + + + 200 + 200 + + + + QFrame::Box + + + QFrame::Plain + + + 1 + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + + + 112 + 184 + 138 + + + + + + + 127 + 127 + 127 + + + + + + 0.000000000000000 + 0.000000000000000 + 400.000000000000000 + 400.000000000000000 + + + + Qt::AlignCenter + + + QGraphicsView::AnchorViewCenter + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + + + + QLayout::SetNoConstraint + + + 3 + + + 3 + + + + + true + + + + 0 + 0 + + + + + 50 + 100 + + + + + 50 + 600 + + + + + 9 + 75 + true + + + + QGroupBox::title { + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +margin:1px; + } + + + REVO + + + + 0 + + + 3 + + + + + false + + + + 7 + + + + 100% + + + Qt::AlignCenter + + + + + + + + + true + + + + 0 + 0 + + + + + 0 + 100 + + + + 100 + + + 5 + + + Qt::Vertical + + + + + + + + + false + + + + 7 + + + + 0% + + + Qt::AlignCenter + + + + + + + + + + + + + true + + + + 0 + 0 + + + + + 60 + 100 + + + + + 50 + 600 + + + + + 9 + 75 + true + + + + QGroupBox::title { + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +margin:1px; + } + + + CCPM + + + Qt::AlignCenter + + + + 0 + + + 3 + + + + + true + + + + 7 + + + + Collective + + + true + + + Qt::AlignCenter + + + + + + + + + true + + + + 0 + 0 + + + + + 0 + 100 + + + + 100 + + + 5 + + + 50 + + + Qt::Vertical + + + + + + + + + true + + + + 7 + + + + Cyclic + + + Qt::AlignCenter + + + + + + + 100 + + + 5 + + + 50 + + + + + + + + + + true + + + + 0 + 0 + + + + + 70 + 100 + + + + + 50 + 600 + + + + + 9 + 75 + true + + + + QGroupBox::title { + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +margin:1px; + } + + + Collective + + + Qt::AlignCenter + + + + 0 + + + 3 + + + + + + + true + + + + 0 + 0 + + + + + 0 + 100 + + + + 100 + + + 5 + + + 50 + + + Qt::Vertical + + + + + + + + + 100 + + + 5 + + + 50 + + + + + + + + + + true + + + + 0 + 0 + + + + + 50 + 100 + + + + + 50 + 600 + + + + + 9 + 75 + true + + + + QGroupBox::title { + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +margin:1px; + } + + + Cyclic + + + Qt::AlignCenter + + + false + + + + 0 + + + 3 + + + + + + + true + + + + 0 + 0 + + + + + 0 + 100 + + + + 100 + + + 5 + + + 50 + + + Qt::Vertical + + + + + + + + + 100 + + + 5 + + + 50 + + + + + + + + + + true + + + + 0 + 0 + + + + + 50 + 100 + + + + + 50 + 600 + + + + + 9 + 75 + true + + + + QGroupBox::title { + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +margin:1px; + } + + + Pitch + + + Qt::AlignCenter + + + + 0 + + + 3 + + + + + + + true + + + + 0 + 0 + + + + + 0 + 100 + + + + 100 + + + 5 + + + 50 + + + Qt::Vertical + + + + + + + + + 100 + + + 5 + + + 50 + + + + + + + + + + true + + + + 0 + 0 + + + + + 50 + 100 + + + + + 50 + 600 + + + + + 9 + 75 + true + + + + QGroupBox::title { + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +margin:1px; + } + + + Roll + + + Qt::AlignCenter + + + + 0 + + + 3 + + + + + + + true + + + + 0 + 0 + + + + + 0 + 100 + + + + 100 + + + 5 + + + 50 + + + Qt::Vertical + + + + + + + + + 100 + + + 5 + + + 50 + + + + + + + + + + + + + Swashplate Levelling + + + + 9 + + + 6 + + + + + 3 + + + + + + 0 + 0 + + + + + 228 + 0 + + + + Commands + + + + 3 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 0 + + + + + + 85 + 0 + + + + + 85 + 16777215 + + + + Start + + + + + + + false + + + + 85 + 0 + + + + + 85 + 16777215 + + + + Next + + + + + + + + + + 0 + 150 + + + + + 220 + 450 + + + + Qt::ScrollBarAlwaysOff + + + true + + + + + + + + + false + + + + 170 + 0 + + + + + 170 + 16777215 + + + + Cancel + + + + + + + false + + + + 170 + 0 + + + + + 170 + 16777215 + + + + Finish + + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + Status + + + + 3 + + + 2 + + + 3 + + + + + + 220 + 0 + + + + + 190 + 125 + + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::NoSelection + + + QAbstractItemView::SelectRows + + + + Neutral + + + + :/configgadget/images/none.png + :/configgadget/images/ok.png:/configgadget/images/none.png + + + + + Max + + + + :/configgadget/images/none.png + :/configgadget/images/ok.png:/configgadget/images/none.png + + + + + Min + + + + :/configgadget/images/none.png + :/configgadget/images/ok.png:/configgadget/images/none.png + + + ItemIsSelectable|ItemIsEnabled + + + + + Verify + + + + :/configgadget/images/none.png + :/configgadget/images/ok.png:/configgadget/images/none.png + + + ItemIsEnabled + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 0 + + + + + + + + + + true + + + + 0 + 0 + + + + + 70 + 100 + + + + + 50 + 600 + + + + Position + + + Qt::AlignCenter + + + + 0 + + + 3 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + true + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + Max + + + true + + + Qt::AlignCenter + + + + + + + + + true + + + + 0 + 0 + + + + + 0 + 100 + + + + 100 + + + 5 + + + 50 + + + Qt::Vertical + + + + + + + + + true + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + Min + + + Qt::AlignCenter + + + + + + + 100 + + + 5 + + + 50 + + + + + + + + + + + 1 + 1 + + + + + 200 + 200 + + + + + 600 + 600 + + + + + 10 + 10 + + + + + 200 + 200 + + + + Swashplate Adjustment + + + Qt::AlignHCenter|Qt::AlignTop + + + false + + + false + + + + 3 + + + 3 + + + + + Qt::Vertical + + + + + 1 + 1 + + + + + 10 + 10 + + + + + 1000 + 1000 + + + + + 10 + 10 + + + + + 200 + 200 + + + + QFrame::Box + + + QFrame::Plain + + + 1 + + + 0 + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + + + 126 + 176 + 220 + + + + + + + 0 + 0 + 0 + + + + + + 0.000000000000000 + 0.000000000000000 + 400.000000000000000 + 400.000000000000000 + + + + Qt::AlignCenter + + + QGraphicsView::AnchorViewCenter + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + + + Curve settings + + + + 9 + + + 6 + + + + + + + + 3 + + + + + + 1 + 1 + + + + + 100 + 100 + + + + + 10 + 10 + + + + + 100 + 100 + + + + Qt::LeftToRight + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + + 0 + + + 0 + + + + + + 1 + 1 + + + + + 50 + 50 + + + + + 1000 + 1000 + + + + + 10 + 10 + + + + + 200 + 200 + + + + + + + + + + + + 1 + 1 + + + + + 100 + 100 + + + + + 10 + 10 + + + + + 100 + 100 + + + + + + + + 0 + + + 0 + + + + + + 1 + 1 + + + + + 50 + 50 + + + + + 1000 + 1000 + + + + + 10 + 10 + + + + + 200 + 200 + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Preferred + + + + 20 + 0 + + + + + + + + + Advanced settings + + + + 9 + + + 6 + + + + + + 0 + 0 + + + + + 0 + 200 + + + + + 1000 + 300 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + true + + + true + + + QAbstractItemView::NoSelection + + + false + + + true + + + 75 + + + 20 + + + + Engine + + + + + Tail Rotor + + + + + Servo W + + + + + Servo X + + + + + Servo Y + + + + + Servo Z + + + + + Channel + + + + + Curve 1 + + + + + Curve 2 + + + + + Roll + + + + + Pitch + + + + + Yaw + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 40 + + + + + + + + + + + + + + + MixerCurve + QWidget +
mixercurve.h
+ 1 +
+
+ + ccpmType + TabObject + ccpmEngineChannel + ccpmTailChannel + ccpmServoWChannel + ccpmServoXChannel + ccpmServoYChannel + ccpmServoZChannel + ccpmSingleServo + ccpmAngleW + ccpmAngleX + ccpmAngleY + ccpmAngleZ + ccpmCorrectionAngle + ccpmRevoSlider + ccpmREVOspinBox + ccpmCollectiveSlider + ccpmCollectivespinBox + SwashplateImage + SwashLvlStartButton + SwashLvlNextButton + SwashLvlStepInstruction + SwashLvlCancelButton + SwashLvlFinishButton + SwashLvlStepList + SwashLvlPositionSlider + SwashLvlPositionSpinBox + SwashLvlSwashplateImage + ccpmAdvancedSettingsTable + + + + + ccpmCollectiveSlider + valueChanged(int) + ccpmCollectivespinBox + setValue(int) + + + 261 + 496 + + + 269 + 546 + + + + + ccpmCollectivespinBox + valueChanged(int) + ccpmCollectiveSlider + setValue(int) + + + 269 + 546 + + + 261 + 511 + + + + + ccpmREVOspinBox + valueChanged(int) + ccpmRevoSlider + setValue(int) + + + 216 + 546 + + + 208 + 511 + + + + + ccpmRevoSlider + valueChanged(int) + ccpmREVOspinBox + setValue(int) + + + 208 + 412 + + + 216 + 546 + + + + + SwashLvlPositionSlider + valueChanged(int) + SwashLvlPositionSpinBox + setValue(int) + + + 276 + 486 + + + 270 + 537 + + + + + SwashLvlPositionSpinBox + valueChanged(int) + SwashLvlPositionSlider + setValue(int) + + + 301 + 546 + + + 277 + 401 + + + + + ccpmCollectiveScaleBox + valueChanged(int) + ccpmCollectiveScale + setValue(int) + + + 296 + 534 + + + 306 + 480 + + + + + ccpmCollectiveScale + valueChanged(int) + ccpmCollectiveScaleBox + setValue(int) + + + 308 + 328 + + + 292 + 534 + + + + + ccpmPitchScale + valueChanged(int) + ccpmPitchScaleBox + setValue(int) + + + 417 + 306 + + + 406 + 531 + + + + + ccpmPitchScaleBox + valueChanged(int) + ccpmPitchScale + setValue(int) + + + 394 + 531 + + + 408 + 302 + + + + + ccpmRollScaleBox + valueChanged(int) + ccpmRollScale + setValue(int) + + + 455 + 529 + + + 458 + 466 + + + + + ccpmRollScale + valueChanged(int) + ccpmRollScaleBox + setValue(int) + + + 461 + 388 + + + 474 + 533 + + + + + ccpmCyclicScale + valueChanged(int) + ccpmCyclicScaleBox + setValue(int) + + + 358 + 306 + + + 355 + 538 + + + + + ccpmCyclicScaleBox + valueChanged(int) + ccpmCyclicScale + setValue(int) + + + 341 + 538 + + + 351 + 376 + + + + +
diff --git a/ground/openpilotgcs/src/plugins/config/airframe_custom.ui b/ground/openpilotgcs/src/plugins/config/airframe_custom.ui new file mode 100644 index 000000000..189356db1 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/config/airframe_custom.ui @@ -0,0 +1,831 @@ + + + CustomConfigWidget + + + + 0 + 0 + 880 + 608 + + + + Form + + + + 0 + + + + + 0 + + + + + + 0 + 0 + + + + Curve 1 + + + + + + + 1 + 1 + + + + + 50 + 50 + + + + + 1000 + 1000 + + + + + 10 + 10 + + + + + 300 + 350 + + + + + + + + + + + Curve 2 + + + + + + + 1 + 1 + + + + + 50 + 50 + + + + + 1000 + 1000 + + + + + 10 + 10 + + + + + 300 + 350 + + + + + + + + + + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + true + + + 12 + + + 50 + + + false + + + + Type + + + + + Curve 1 + + + + + Curve 2 + + + + + Roll + + + + + Pitch + + + + + Yaw + + + + + Ch 1 + + + + + Ch 2 + + + + + Ch 3 + + + + + Ch 4 + + + + + Ch 5 + + + + + Ch 6 + + + + + Ch 7 + + + + + Ch 8 + + + + + Ch 9 + + + + + Ch 10 + + + + + Ch 11 + + + + + Ch 12 + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + - + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + + + + + + + MixerCurve + QWidget +
mixercurve.h
+ 1 +
+
+ + + + +
diff --git a/ground/openpilotgcs/src/plugins/config/airframe_fixedwing.ui b/ground/openpilotgcs/src/plugins/config/airframe_fixedwing.ui new file mode 100644 index 000000000..1b42f042d --- /dev/null +++ b/ground/openpilotgcs/src/plugins/config/airframe_fixedwing.ui @@ -0,0 +1,507 @@ + + + FixedWingConfigWidget + + + + 0 + 0 + 880 + 608 + + + + Form + + + + 0 + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Airplane type: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + + + + + + 0 + 0 + + + + + 230 + 100 + + + + Output Channel Assignments + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Engine + + + + + + + Select output channel for the engine + + + + + + + + 60 + 0 + + + + Aileron 1 + + + + + + + Select output channel for the first aileron (or elevon) + + + + + + + true + + + + 60 + 0 + + + + Aileron 2 + + + + + + + true + + + Select output channel for the second aileron (or elevon) + + + + + + + + 67 + 0 + + + + Elevator 1 + + + + + + + Select output channel for the first elevator + + + + + + + true + + + + 67 + 0 + + + + Elevator 2 + + + + + + + true + + + Select output channel for a secondary elevator + + + + + + + Rudder 1 + + + + + + + Select output channel for the first rudder + + + + + + + Rudder 2 + + + + + + + Select output channel for a secondary rudder + + + + + + + + + + + 0 + 0 + + + + Elevon Mix + + + + + + + + + + + 65 + 0 + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + Rudder % + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + 100 + + + 50 + + + Qt::Vertical + + + + + + + 50 + + + Qt::AlignCenter + + + + + + + + + + + + 65 + 0 + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + Pitch % + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + 100 + + + 50 + + + Qt::Vertical + + + + + + + 50 + + + Qt::AlignCenter + + + + + + + + + + + + + + + 0 + 100 + + + + Throttle Curve + + + + + + + 1 + 1 + + + + + 0 + 0 + + + + + 500 + 500 + + + + + 10 + 10 + + + + + 300 + 350 + + + + + + + + + + + Qt::Horizontal + + + + 0 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 75 + true + + + + Mixer OK + + + + + + + + + + MixerCurve + QWidget +
mixercurve.h
+ 1 +
+
+ + + + + + elevonSlider1 + valueChanged(int) + elevonSliderLabel1 + setNum(int) + + + 124 + 126 + + + 124 + 126 + + + + + elevonSlider2 + valueChanged(int) + elevonSliderLabel2 + setNum(int) + + + 362 + 299 + + + 124 + 126 + + + + +
diff --git a/ground/openpilotgcs/src/plugins/config/airframe_ground.ui b/ground/openpilotgcs/src/plugins/config/airframe_ground.ui new file mode 100644 index 000000000..de21f3ad2 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/config/airframe_ground.ui @@ -0,0 +1,569 @@ + + + GroundConfigWidget + + + + 0 + 0 + 880 + 608 + + + + Form + + + + 0 + + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 75 + true + + + + Vehicle type: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Output channel assignments + + + + + + + 77 + 0 + + + + Engine + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Select output channel for the engine + + + + + + + + 60 + 0 + + + + Aileron 1 + + + + + + + Select output channel for the first aileron (or elevon) + + + + + + + true + + + + 60 + 0 + + + + Aileron 2 + + + + + + + true + + + Select output channel for the second aileron (or elevon) + + + + + + + + 0 + 0 + + + + Motor + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Select output channel for the first motor + + + + + + + true + + + + 47 + 0 + + + + Motor 2 + + + + + + + true + + + Select output channel for a second motor + + + + + + + Front Steering + + + + + + + Select output channel for the first steering actuator + + + + + + + Rear Steering + + + + + + + Select output channel for a second steering actuator + + + + + + + + + + true + + + + 0 + 0 + + + + Differential Steering Mix + + + + + + + + + + + 65 + 0 + + + + + -1 + 75 + false + true + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + Left % + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + 100 + + + 50 + + + Qt::Vertical + + + + + + + 50 + + + Qt::AlignCenter + + + + + + + + + + + + 65 + 0 + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + Right % + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + 100 + + + 50 + + + Qt::Vertical + + + + + + + 50 + + + Qt::AlignCenter + + + + + + + + + + + + + + + 0 + 100 + + + + Front throttle curve + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + Rear throttle curve + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 75 + true + + + + Mixer OK + + + + + + + + + + MixerCurve + QWidget +
mixercurve.h
+ 1 +
+
+ + + + + + differentialSteeringSlider1 + valueChanged(int) + gvDiffSteering1Label + setNum(int) + + + 124 + 126 + + + 315 + 391 + + + + + differentialSteeringSlider2 + valueChanged(int) + gvDiffSteering2Label + setNum(int) + + + 124 + 126 + + + 390 + 391 + + + + +
diff --git a/ground/openpilotgcs/src/plugins/config/airframe_multirotor.ui b/ground/openpilotgcs/src/plugins/config/airframe_multirotor.ui new file mode 100644 index 000000000..a8e038f74 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/config/airframe_multirotor.ui @@ -0,0 +1,860 @@ + + + MultiRotorConfigWidget + + + + 0 + 0 + 880 + 608 + + + + Form + + + + 0 + + + + + + 10 + 10 + + + + + 16777215 + 16777215 + + + + Frame + + + + 9 + + + + + + 0 + 0 + + + + + 10 + 10 + + + + background:transparent + + + QFrame::NoFrame + + + QFrame::Plain + + + + + + + + + + + 0 + 0 + + + + + 10 + 10 + + + + + 16777215 + 16777215 + + + + Throttle Curve + + + + 9 + + + + + + 0 + 0 + + + + + 10 + 10 + + + + + 10 + 10 + + + + + 50 + 50 + + + + background:transparent + + + + + + + + + + + 16777215 + 16777215 + + + + Mix Level + + + + 0 + + + 9 + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 16777215 + 16777215 + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + Roll + + + Qt::AlignCenter + + + + + + + + 40 + 0 + + + + Weight of Roll mixing in percent. +Typical values are 100% for + configuration and 50% for X configuration on quads. + + + 100 + + + 50 + + + Qt::Vertical + + + + + + + + 40 + 0 + + + + 50 + + + Qt::AlignCenter + + + + + + + + + + + + 40 + 0 + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + Pitch + + + Qt::AlignCenter + + + + + + + + 40 + 0 + + + + Weight of Pitch mixing in percent. +Typical values are 100% for + configuration and 50% for X configuration on quads. + + + 100 + + + 50 + + + Qt::Vertical + + + + + + + + 40 + 0 + + + + 50 + + + Qt::AlignCenter + + + + + + + + + + + + 40 + 0 + + + + false + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + Yaw + + + Qt::AlignCenter + + + + + + + + 40 + 0 + + + + Weight of Yaw mixing in percent. +Typical value is 50% for + or X configuration on quads. + + + 0 + + + 100 + + + 50 + + + Qt::Vertical + + + + + + + + 40 + 0 + + + + 50 + + + Qt::AlignCenter + + + + + + + + + + + + QLayout::SetFixedSize + + + + + + 75 + true + + + + Frame Type: + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 16777215 + 25 + + + + Select the Multirotor frame type here. + + + + + + + Qt::Horizontal + + + + 10 + 13 + + + + + + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Mixer OK + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + 0 + 0 + + + + + 0 + 140 + + + + Motor output channels + + + + 9 + + + + + QLayout::SetMaximumSize + + + QFormLayout::AllNonFixedFieldsGrow + + + 6 + + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + 1 + + + + + + + Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. + + + + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + 2 + + + + + + + Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. + + + + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + 3 + + + + + + + Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. + + + + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + 4 + + + + + + + Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. + + + + + + + + + QLayout::SetMaximumSize + + + QFormLayout::AllNonFixedFieldsGrow + + + 6 + + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + 5 + + + + + + + true + + + + 0 + 0 + + + + Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. + + + + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + 6 + + + + + + + true + + + Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. + + + + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + 7 + + + + + + + true + + + Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. + + + + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + 8 + + + + + + + true + + + Assign your motor output channels using the drawing above as a reference. Respect propeller rotation. + + + + + + + + + + 0 + 0 + + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + + 0 + 16 + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + Multirotor Motor Direction + + + Qt::AlignCenter + + + + + + + true + + + + 0 + 0 + + + + + 40 + 0 + + + + + + + + + 0 + 0 + + + + + 0 + 16 + + + + background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255)); +color: rgb(255, 255, 255); +border-radius: 5; +font: bold 12px; +margin:1px; + + + Tricopter Yaw Servo channel + + + Qt::AlignCenter + + + + + + + Reverse all motors + + + + + + + + + + + MixerCurve + QWidget +
mixercurve.h
+ 1 +
+
+ + + + + + mrRollMixLevel + valueChanged(int) + mrRollMixValue + setNum(int) + + + 42 + 220 + + + 43 + 171 + + + + + mrYawMixLevel + valueChanged(int) + mrYawMixValue + setNum(int) + + + 120 + 254 + + + 121 + 172 + + + + + mrPitchMixLevel + valueChanged(int) + mrPitchMixValue + setNum(int) + + + 92 + 222 + + + 92 + 151 + + + + +
diff --git a/ground/openpilotgcs/src/plugins/config/ccpm.ui b/ground/openpilotgcs/src/plugins/config/ccpm_old.ui similarity index 100% rename from ground/openpilotgcs/src/plugins/config/ccpm.ui rename to ground/openpilotgcs/src/plugins/config/ccpm_old.ui diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.cpp b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.cpp index 4ea8dd670..6e764dc41 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.cpp @@ -25,6 +25,9 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configccpmwidget.h" +#include "mixersettings.h" +#include "systemsettings.h" +#include "actuatorcommand.h" #include #include @@ -33,52 +36,122 @@ #include #include #include -#include #include -#include "mixersettings.h" -#include "systemsettings.h" -#include "actuatorcommand.h" +#include -#define Pi 3.14159265358979323846 +#define Pi 3.14159265358979323846 - -ConfigCcpmWidget::ConfigCcpmWidget(QWidget *parent) : VehicleConfig(parent) +QStringList ConfigCcpmWidget::getChannelDescriptions() { - int i; - SwashLvlConfigurationInProgress=0; - SwashLvlState=0; - SwashLvlServoInterlock=0; - updatingFromHardware=FALSE; - updatingToHardware=FALSE; + // init a channel_numelem list of channel desc defaults + QStringList channelDesc; + for (int i = 0; i < (int) ConfigCcpmWidget::CHANNEL_NUMELEM; i++) { + channelDesc.append(QString("-")); + } - m_ccpm = new Ui_ccpmWidget(); - m_ccpm->setupUi(this); + // get the gui config data + GUIConfigDataUnion configData = getConfigData(); + heliGUISettingsStruct heli = configData.heli; + + if (heli.Throttle > 0) { + channelDesc[heli.Throttle - 1] = QString("Throttle"); + } + if (heli.Tail > 0) { + channelDesc[heli.Tail - 1] = QString("Tail"); + } + + switch (heli.FirstServoIndex) { + case 0: + // front + if (heli.ServoIndexW > 0) { + channelDesc[heli.ServoIndexW - 1] = QString("Elevator"); + } + if (heli.ServoIndexX > 0) { + channelDesc[heli.ServoIndexX - 1] = QString("Roll1"); + } + if (heli.ServoIndexY > 0) { + channelDesc[heli.ServoIndexY - 1] = QString("Roll2"); + } + break; + case 1: + // right + if (heli.ServoIndexW > 0) { + channelDesc[heli.ServoIndexW - 1] = QString("ServoW"); + } + if (heli.ServoIndexX > 0) { + channelDesc[heli.ServoIndexX - 1] = QString("ServoX"); + } + if (heli.ServoIndexY > 0) { + channelDesc[heli.ServoIndexY - 1] = QString("ServoY"); + } + break; + case 2: + // rear + if (heli.ServoIndexW > 0) { + channelDesc[heli.ServoIndexW - 1] = QString("Elevator"); + } + if (heli.ServoIndexX > 0) { + channelDesc[heli.ServoIndexX - 1] = QString("Roll1"); + } + if (heli.ServoIndexY > 0) { + channelDesc[heli.ServoIndexY - 1] = QString("Roll2"); + } + break; + case 3: + // left + if (heli.ServoIndexW > 0) { + channelDesc[heli.ServoIndexW - 1] = QString("ServoW"); + } + if (heli.ServoIndexX > 0) { + channelDesc[heli.ServoIndexX - 1] = QString("ServoX"); + } + if (heli.ServoIndexY > 0) { + channelDesc[heli.ServoIndexY - 1] = QString("ServoY"); + } + break; + } + if (heli.ServoIndexZ > 0) { + channelDesc[heli.ServoIndexZ - 1] = QString("ServoZ"); + } + return channelDesc; +} + +ConfigCcpmWidget::ConfigCcpmWidget(QWidget *parent) : + VehicleConfig(parent), m_aircraft(new Ui_CcpmConfigWidget()) +{ + m_aircraft->setupUi(this); + + SwashLvlConfigurationInProgress = 0; + SwashLvlState = 0; + SwashLvlServoInterlock = 0; + updatingFromHardware = FALSE; + updatingToHardware = FALSE; // Initialization of the swashplaye widget - m_ccpm->SwashplateImage->setScene(new QGraphicsScene(this)); + m_aircraft->SwashplateImage->setScene(new QGraphicsScene(this)); - m_ccpm->SwashLvlSwashplateImage->setScene(m_ccpm->SwashplateImage->scene()); - m_ccpm->SwashLvlSwashplateImage->setSceneRect(-50,-50,500,500); - //m_ccpm->SwashLvlSwashplateImage->scale(.85,.85); + m_aircraft->SwashLvlSwashplateImage->setScene(m_aircraft->SwashplateImage->scene()); + m_aircraft->SwashLvlSwashplateImage->setSceneRect(-50, -50, 500, 500); + //m_aircraft->SwashLvlSwashplateImage->scale(.85,.85); - //m_ccpm->SwashplateImage->setSceneRect(SwashplateImg->boundingRect()); - m_ccpm->SwashplateImage->setSceneRect(-50,-30,500,500); - //m_ccpm->SwashplateImage->scale(.85,.85); + //m_aircraft->SwashplateImage->setSceneRect(SwashplateImg->boundingRect()); + m_aircraft->SwashplateImage->setSceneRect(-50, -30, 500, 500); + //m_aircraft->SwashplateImage->scale(.85,.85); QSvgRenderer *renderer = new QSvgRenderer(); renderer->load(QString(":/configgadget/images/ccpm_setup.svg")); - SwashplateImg = new QGraphicsSvgItem(); SwashplateImg->setSharedRenderer(renderer); SwashplateImg->setElementId("Swashplate"); SwashplateImg->setObjectName("Swashplate"); //SwashplateImg->setScale(0.75); - m_ccpm->SwashplateImage->scene()->addItem(SwashplateImg); + m_aircraft->SwashplateImage->scene()->addItem(SwashplateImg); QFont serifFont("Times", 24, QFont::Bold); - QPen pen; // creates a default pen + // creates a default pen + QPen pen; pen.setStyle(Qt::DotLine); pen.setWidth(2); @@ -86,123 +159,117 @@ ConfigCcpmWidget::ConfigCcpmWidget(QWidget *parent) : VehicleConfig(parent) pen.setCapStyle(Qt::RoundCap); pen.setJoinStyle(Qt::RoundJoin); - QBrush brush(Qt::darkBlue); - QPen pen2; // creates a default pen - + // creates a default pen + QPen pen2; + //pen2.setStyle(Qt::DotLine); pen2.setWidth(1); pen2.setBrush(Qt::blue); //pen2.setCapStyle(Qt::RoundCap); //pen2.setJoinStyle(Qt::RoundJoin); - - - //brush.setStyle(Qt::RadialGradientPattern); - - QList ServoNames; - ServoNames << "ServoW" << "ServoX" << "ServoY" << "ServoZ" ; - for (i=0;iSwashLvlSwashplateImage->scene()->addLine(0,0,100*i,i*i*100,pen); + //brush.setStyle(Qt::RadialGradientPattern); + + QList ServoNames; + ServoNames << "ServoW" << "ServoX" << "ServoY" << "ServoZ"; + + for (int i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) { + ServoLines[i] = m_aircraft->SwashLvlSwashplateImage->scene()->addLine(0, 0, 100 * i, i * i * 100, pen); Servos[i] = new QGraphicsSvgItem(); Servos[i]->setSharedRenderer(renderer); Servos[i]->setElementId(ServoNames.at(i)); - m_ccpm->SwashplateImage->scene()->addItem(Servos[i]); + m_aircraft->SwashplateImage->scene()->addItem(Servos[i]); ServosText[i] = new QGraphicsTextItem(); ServosText[i]->setDefaultTextColor(Qt::yellow); ServosText[i]->setPlainText(QString("-")); ServosText[i]->setFont(serifFont); - - ServosTextCircles[i] = new QGraphicsEllipseItem(1,1,30,30); + + ServosTextCircles[i] = new QGraphicsEllipseItem(1, 1, 30, 30); ServosTextCircles[i]->setBrush(brush); ServosTextCircles[i]->setPen(pen2); - m_ccpm->SwashplateImage->scene()->addItem(ServosTextCircles[i]); - m_ccpm->SwashplateImage->scene()->addItem(ServosText[i]); - + m_aircraft->SwashplateImage->scene()->addItem(ServosTextCircles[i]); + m_aircraft->SwashplateImage->scene()->addItem(ServosText[i]); - - SwashLvlSpinBoxes[i] = new QSpinBox(m_ccpm->SwashLvlSwashplateImage); // use QGraphicsView - m_ccpm->SwashLvlSwashplateImage->scene()->addWidget(SwashLvlSpinBoxes[i]); + SwashLvlSpinBoxes[i] = new QSpinBox(m_aircraft->SwashLvlSwashplateImage); // use QGraphicsView + m_aircraft->SwashLvlSwashplateImage->scene()->addWidget(SwashLvlSpinBoxes[i]); SwashLvlSpinBoxes[i]->setMaximum(10000); SwashLvlSpinBoxes[i]->setMinimum(0); SwashLvlSpinBoxes[i]->setValue(0); } - //initialize our two mixer curves + // initialize our two mixer curves // mixercurve defaults to mixercurve_throttle - m_ccpm->ThrottleCurve->initLinearCurve(5, 1.0, 0.0); + m_aircraft->ThrottleCurve->initLinearCurve(5, 1.0, 0.0); // tell mixercurve this is a pitch curve - m_ccpm->PitchCurve->setMixerType(MixerCurve::MIXERCURVE_PITCH); - m_ccpm->PitchCurve->initLinearCurve(5, 1.0, -1.0); + m_aircraft->PitchCurve->setMixerType(MixerCurve::MIXERCURVE_PITCH); + m_aircraft->PitchCurve->initLinearCurve(5, 1.0, -1.0); - //initialize channel names - m_ccpm->ccpmEngineChannel->addItems(channelNames); - m_ccpm->ccpmEngineChannel->setCurrentIndex(0); - m_ccpm->ccpmTailChannel->addItems(channelNames); - m_ccpm->ccpmTailChannel->setCurrentIndex(0); - m_ccpm->ccpmServoWChannel->addItems(channelNames); - m_ccpm->ccpmServoWChannel->setCurrentIndex(0); - m_ccpm->ccpmServoXChannel->addItems(channelNames); - m_ccpm->ccpmServoXChannel->setCurrentIndex(0); - m_ccpm->ccpmServoYChannel->addItems(channelNames); - m_ccpm->ccpmServoYChannel->setCurrentIndex(0); - m_ccpm->ccpmServoZChannel->addItems(channelNames); - m_ccpm->ccpmServoZChannel->setCurrentIndex(0); + // initialize channel names + m_aircraft->ccpmEngineChannel->addItems(channelNames); + m_aircraft->ccpmEngineChannel->setCurrentIndex(0); + m_aircraft->ccpmTailChannel->addItems(channelNames); + m_aircraft->ccpmTailChannel->setCurrentIndex(0); + m_aircraft->ccpmServoWChannel->addItems(channelNames); + m_aircraft->ccpmServoWChannel->setCurrentIndex(0); + m_aircraft->ccpmServoXChannel->addItems(channelNames); + m_aircraft->ccpmServoXChannel->setCurrentIndex(0); + m_aircraft->ccpmServoYChannel->addItems(channelNames); + m_aircraft->ccpmServoYChannel->setCurrentIndex(0); + m_aircraft->ccpmServoZChannel->addItems(channelNames); + m_aircraft->ccpmServoZChannel->setCurrentIndex(0); QStringList Types; - Types << QString::fromUtf8("CCPM 2 Servo 90º") << QString::fromUtf8("CCPM 3 Servo 90º") << QString::fromUtf8("CCPM 4 Servo 90º") << - QString::fromUtf8("CCPM 3 Servo 120º") << QString::fromUtf8("CCPM 3 Servo 140º") << - QString::fromUtf8("FP 2 Servo 90º") << - QString::fromUtf8("Coax 2 Servo 90º") << - QString::fromUtf8("Custom - User Angles") << QString::fromUtf8("Custom - Advanced Settings"); - m_ccpm->ccpmType->addItems(Types); - m_ccpm->ccpmType->setCurrentIndex(m_ccpm->ccpmType->count() - 1); + Types << QString::fromUtf8("CCPM 2 Servo 90º") << QString::fromUtf8("CCPM 3 Servo 90º") + << QString::fromUtf8("CCPM 4 Servo 90º") << QString::fromUtf8("CCPM 3 Servo 120º") + << QString::fromUtf8("CCPM 3 Servo 140º") << QString::fromUtf8("FP 2 Servo 90º") + << QString::fromUtf8("Coax 2 Servo 90º") << QString::fromUtf8("Custom - User Angles") + << QString::fromUtf8("Custom - Advanced Settings"); + m_aircraft->ccpmType->addItems(Types); + m_aircraft->ccpmType->setCurrentIndex(m_aircraft->ccpmType->count() - 1); - refreshWidgetsValues(QString("HeliCP")); + //refreshWidgetsValues(QString("HeliCP")); UpdateType(); - connect(m_ccpm->ccpmAngleW, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate())); - connect(m_ccpm->ccpmAngleX, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate())); - connect(m_ccpm->ccpmAngleY, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate())); - connect(m_ccpm->ccpmAngleZ, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate())); - connect(m_ccpm->ccpmCorrectionAngle, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate())); - connect(m_ccpm->ccpmServoWChannel, SIGNAL(currentIndexChanged(int)), this, SLOT(ccpmSwashplateUpdate())); - connect(m_ccpm->ccpmServoXChannel, SIGNAL(currentIndexChanged(int)), this, SLOT(ccpmSwashplateUpdate())); - connect(m_ccpm->ccpmServoYChannel, SIGNAL(currentIndexChanged(int)), this, SLOT(ccpmSwashplateUpdate())); - connect(m_ccpm->ccpmServoZChannel, SIGNAL(currentIndexChanged(int)), this, SLOT(ccpmSwashplateUpdate())); - connect(m_ccpm->ccpmEngineChannel, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateMixer())); - connect(m_ccpm->ccpmTailChannel, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateMixer())); - connect(m_ccpm->ccpmRevoSlider, SIGNAL(valueChanged(int)), this, SLOT(UpdateMixer())); - connect(m_ccpm->ccpmREVOspinBox, SIGNAL(valueChanged(int)), this, SLOT(UpdateMixer())); - connect(m_ccpm->ccpmCollectiveSlider, SIGNAL(valueChanged(int)), this, SLOT(UpdateMixer())); - connect(m_ccpm->ccpmCollectivespinBox, SIGNAL(valueChanged(int)), this, SLOT(UpdateMixer())); - connect(m_ccpm->ccpmType, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateType())); - connect(m_ccpm->ccpmSingleServo, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateType())); - connect(m_ccpm->TabObject, SIGNAL(currentChanged ( QWidget * )), this, SLOT(UpdateType())); + connect(m_aircraft->ccpmAngleW, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate())); + connect(m_aircraft->ccpmAngleX, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate())); + connect(m_aircraft->ccpmAngleY, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate())); + connect(m_aircraft->ccpmAngleZ, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate())); + connect(m_aircraft->ccpmCorrectionAngle, SIGNAL(valueChanged(double)), this, SLOT(ccpmSwashplateUpdate())); + connect(m_aircraft->ccpmServoWChannel, SIGNAL(currentIndexChanged(int)), this, SLOT(ccpmSwashplateUpdate())); + connect(m_aircraft->ccpmServoXChannel, SIGNAL(currentIndexChanged(int)), this, SLOT(ccpmSwashplateUpdate())); + connect(m_aircraft->ccpmServoYChannel, SIGNAL(currentIndexChanged(int)), this, SLOT(ccpmSwashplateUpdate())); + connect(m_aircraft->ccpmServoZChannel, SIGNAL(currentIndexChanged(int)), this, SLOT(ccpmSwashplateUpdate())); + connect(m_aircraft->ccpmEngineChannel, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateMixer())); + connect(m_aircraft->ccpmTailChannel, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateMixer())); + connect(m_aircraft->ccpmRevoSlider, SIGNAL(valueChanged(int)), this, SLOT(UpdateMixer())); + connect(m_aircraft->ccpmREVOspinBox, SIGNAL(valueChanged(int)), this, SLOT(UpdateMixer())); + connect(m_aircraft->ccpmCollectiveSlider, SIGNAL(valueChanged(int)), this, SLOT(UpdateMixer())); + connect(m_aircraft->ccpmCollectivespinBox, SIGNAL(valueChanged(int)), this, SLOT(UpdateMixer())); + connect(m_aircraft->ccpmType, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateType())); + connect(m_aircraft->ccpmSingleServo, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateType())); + connect(m_aircraft->TabObject, SIGNAL(currentChanged ( QWidget * )), this, SLOT(UpdateType())); - connect(m_ccpm->SwashLvlStartButton, SIGNAL(clicked()), this, SLOT(SwashLvlStartButtonPressed())); - connect(m_ccpm->SwashLvlNextButton, SIGNAL(clicked()), this, SLOT(SwashLvlNextButtonPressed())); - connect(m_ccpm->SwashLvlCancelButton, SIGNAL(clicked()), this, SLOT(SwashLvlCancelButtonPressed())); - connect(m_ccpm->SwashLvlFinishButton, SIGNAL(clicked()), this, SLOT(SwashLvlFinishButtonPressed())); + connect(m_aircraft->SwashLvlStartButton, SIGNAL(clicked()), this, SLOT(SwashLvlStartButtonPressed())); + connect(m_aircraft->SwashLvlNextButton, SIGNAL(clicked()), this, SLOT(SwashLvlNextButtonPressed())); + connect(m_aircraft->SwashLvlCancelButton, SIGNAL(clicked()), this, SLOT(SwashLvlCancelButtonPressed())); + connect(m_aircraft->SwashLvlFinishButton, SIGNAL(clicked()), this, SLOT(SwashLvlFinishButtonPressed())); - connect(m_ccpm->ccpmCollectivePassthrough, SIGNAL(clicked()),this, SLOT(SetUIComponentVisibilities())); - connect(m_ccpm->ccpmLinkCyclic, SIGNAL(clicked()), this, SLOT(SetUIComponentVisibilities())); - connect(m_ccpm->ccpmLinkRoll, SIGNAL(clicked()), this, SLOT(SetUIComponentVisibilities())); + connect(m_aircraft->ccpmCollectivePassthrough, SIGNAL(clicked()), this, SLOT(SetUIComponentVisibilities())); + connect(m_aircraft->ccpmLinkCyclic, SIGNAL(clicked()), this, SLOT(SetUIComponentVisibilities())); + connect(m_aircraft->ccpmLinkRoll, SIGNAL(clicked()), this, SLOT(SetUIComponentVisibilities())); - - - ccpmSwashplateRedraw(); + ccpmSwashplateRedraw(); } ConfigCcpmWidget::~ConfigCcpmWidget() { - // Do nothing + delete m_aircraft; } void ConfigCcpmWidget::setupUI(QString frameType) @@ -210,7 +277,42 @@ void ConfigCcpmWidget::setupUI(QString frameType) Q_UNUSED(frameType); } -void ConfigCcpmWidget::ResetActuators(GUIConfigDataUnion* configData) +void ConfigCcpmWidget::registerWidgets(ConfigTaskWidget &parent) { + parent.addWidget(m_aircraft->ccpmType); + parent.addWidget(m_aircraft->ccpmTailChannel); + parent.addWidget(m_aircraft->ccpmEngineChannel); + parent.addWidget(m_aircraft->ccpmServoWChannel); + parent.addWidget(m_aircraft->ccpmServoXChannel); + parent.addWidget(m_aircraft->ccpmServoYChannel); + parent.addWidget(m_aircraft->ccpmSingleServo); + parent.addWidget(m_aircraft->ccpmServoZChannel); + parent.addWidget(m_aircraft->ccpmAngleW); + parent.addWidget(m_aircraft->ccpmAngleX); + parent.addWidget(m_aircraft->ccpmCorrectionAngle); + parent.addWidget(m_aircraft->ccpmAngleZ); + parent.addWidget(m_aircraft->ccpmAngleY); + parent.addWidget(m_aircraft->ccpmCollectivePassthrough); + parent.addWidget(m_aircraft->ccpmLinkRoll); + parent.addWidget(m_aircraft->ccpmLinkCyclic); + parent.addWidget(m_aircraft->ccpmRevoSlider); + parent.addWidget(m_aircraft->ccpmREVOspinBox); + parent.addWidget(m_aircraft->ccpmCollectiveSlider); + parent.addWidget(m_aircraft->ccpmCollectivespinBox); + parent.addWidget(m_aircraft->ccpmCollectiveScale); + parent.addWidget(m_aircraft->ccpmCollectiveScaleBox); + parent.addWidget(m_aircraft->ccpmCyclicScale); + parent.addWidget(m_aircraft->ccpmPitchScale); + parent.addWidget(m_aircraft->ccpmPitchScaleBox); + parent.addWidget(m_aircraft->ccpmRollScale); + parent.addWidget(m_aircraft->ccpmRollScaleBox); + parent.addWidget(m_aircraft->SwashLvlPositionSlider); + parent.addWidget(m_aircraft->SwashLvlPositionSpinBox); + parent.addWidget(m_aircraft->ThrottleCurve->getCurveWidget()); + parent.addWidget(m_aircraft->PitchCurve->getCurveWidget()); + parent.addWidget(m_aircraft->ccpmAdvancedSettingsTable); +} + +void ConfigCcpmWidget::resetActuators(GUIConfigDataUnion *configData) { configData->heli.Throttle = 0; configData->heli.Tail = 0; @@ -220,260 +322,225 @@ void ConfigCcpmWidget::ResetActuators(GUIConfigDataUnion* configData) configData->heli.ServoIndexZ = 0; } -QStringList ConfigCcpmWidget::getChannelDescriptions() +void ConfigCcpmWidget::refreshWidgetsValues(QString frameType) { - int i; - QStringList channelDesc; + Q_UNUSED(frameType); - // init a channel_numelem list of channel desc defaults - for (i=0; i < (int)(ConfigCcpmWidget::CHANNEL_NUMELEM); i++) - { - channelDesc.append(QString("-")); - } + setupUI(frameType); - // get the gui config data - GUIConfigDataUnion configData = GetConfigData(); - heliGUISettingsStruct heli = configData.heli; + GUIConfigDataUnion config = getConfigData(); - if (heli.Throttle > 0) - channelDesc[heli.Throttle - 1] = QString("Throttle"); - if (heli.Tail > 0) - channelDesc[heli.Tail - 1] = QString("Tail"); + // swashplate config + setComboCurrentIndex(m_aircraft->ccpmType, m_aircraft->ccpmType->count() - (config.heli.SwashplateType + 1)); + setComboCurrentIndex(m_aircraft->ccpmSingleServo, config.heli.FirstServoIndex); - switch(heli.FirstServoIndex) - { - case 0: //front - if (heli.ServoIndexW > 0) - channelDesc[heli.ServoIndexW - 1] = QString("Elevator"); - if (heli.ServoIndexX > 0) - channelDesc[heli.ServoIndexX - 1] = QString("Roll1"); - if (heli.ServoIndexY > 0) - channelDesc[heli.ServoIndexY - 1] = QString("Roll2"); - break; + // ccpm mixing options + m_aircraft->ccpmCollectivePassthrough->setChecked(config.heli.ccpmCollectivePassthroughState); + m_aircraft->ccpmLinkCyclic->setChecked(config.heli.ccpmLinkCyclicState); + m_aircraft->ccpmLinkRoll->setChecked(config.heli.ccpmLinkRollState); - case 1: //right - if (heli.ServoIndexW > 0) - channelDesc[heli.ServoIndexW - 1] = QString("ServoW"); - if (heli.ServoIndexX > 0) - channelDesc[heli.ServoIndexX - 1] = QString("ServoX"); - if (heli.ServoIndexY > 0) - channelDesc[heli.ServoIndexY - 1] = QString("ServoY"); - break; + // correction angle + m_aircraft->ccpmCorrectionAngle->setValue(config.heli.CorrectionAngle); - case 2: //rear - if (heli.ServoIndexW > 0) - channelDesc[heli.ServoIndexW - 1] = QString("Elevator"); - if (heli.ServoIndexX > 0) - channelDesc[heli.ServoIndexX - 1] = QString("Roll1"); - if (heli.ServoIndexY > 0) - channelDesc[heli.ServoIndexY - 1] = QString("Roll2"); - break; + // update sliders + m_aircraft->ccpmCollectiveScale->setValue(config.heli.SliderValue0); + m_aircraft->ccpmCollectiveScaleBox->setValue(config.heli.SliderValue0); + m_aircraft->ccpmCyclicScale->setValue(config.heli.SliderValue1); + m_aircraft->ccpmCyclicScaleBox->setValue(config.heli.SliderValue1); + m_aircraft->ccpmPitchScale->setValue(config.heli.SliderValue1); + m_aircraft->ccpmPitchScaleBox->setValue(config.heli.SliderValue1); + m_aircraft->ccpmRollScale->setValue(config.heli.SliderValue2); + m_aircraft->ccpmRollScaleBox->setValue(config.heli.SliderValue2); + m_aircraft->ccpmCollectiveSlider->setValue(config.heli.SliderValue0); + m_aircraft->ccpmCollectivespinBox->setValue(config.heli.SliderValue0); - case 3: //left - if (heli.ServoIndexW > 0) - channelDesc[heli.ServoIndexW - 1] = QString("ServoW"); - if (heli.ServoIndexX > 0) - channelDesc[heli.ServoIndexX - 1] = QString("ServoX"); - if (heli.ServoIndexY > 0) - channelDesc[heli.ServoIndexY - 1] = QString("ServoY"); - break; + // servo assignments + setComboCurrentIndex(m_aircraft->ccpmServoWChannel, config.heli.ServoIndexW); + setComboCurrentIndex( m_aircraft->ccpmServoXChannel,config.heli.ServoIndexX); + setComboCurrentIndex( m_aircraft->ccpmServoYChannel,config.heli.ServoIndexY); + setComboCurrentIndex( m_aircraft->ccpmServoZChannel,config.heli.ServoIndexZ); - } - if (heli.ServoIndexZ > 0) - channelDesc[heli.ServoIndexZ - 1] = QString("ServoZ"); + // throttle + setComboCurrentIndex( m_aircraft->ccpmEngineChannel, config.heli.Throttle); + // tail + setComboCurrentIndex( m_aircraft->ccpmTailChannel, config.heli.Tail); - return channelDesc; + getMixer(); +} + +QString ConfigCcpmWidget::updateConfigObjectsFromWidgets() +{ + QString airframeType = updateConfigObjects(); + + setMixer(); + + return airframeType; } void ConfigCcpmWidget::UpdateType() { - int TypeInt,SingleServoIndex,NumServosDefined; - double AdjustmentAngle=0; + int TypeInt, SingleServoIndex, NumServosDefined; + double AdjustmentAngle = 0; SetUIComponentVisibilities(); - - TypeInt = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex()-1; - TypeText = m_ccpm->ccpmType->currentText(); - SingleServoIndex = m_ccpm->ccpmSingleServo->currentIndex(); + + TypeInt = m_aircraft->ccpmType->count() - m_aircraft->ccpmType->currentIndex() - 1; + TypeText = m_aircraft->ccpmType->currentText(); + SingleServoIndex = m_aircraft->ccpmSingleServo->currentIndex(); //set visibility of user settings - m_ccpm->ccpmAdvancedSettingsTable->setEnabled(TypeInt==0); - m_ccpm->ccpmAdvancedSettingsTable->clearFocus();; + m_aircraft->ccpmAdvancedSettingsTable->setEnabled(TypeInt == 0); + m_aircraft->ccpmAdvancedSettingsTable->clearFocus(); - m_ccpm->ccpmAngleW->setEnabled(TypeInt==1); - m_ccpm->ccpmAngleX->setEnabled(TypeInt==1); - m_ccpm->ccpmAngleY->setEnabled(TypeInt==1); - m_ccpm->ccpmAngleZ->setEnabled(TypeInt==1); - m_ccpm->ccpmCorrectionAngle->setEnabled(TypeInt!=0); + m_aircraft->ccpmAngleW->setEnabled(TypeInt == 1); + m_aircraft->ccpmAngleX->setEnabled(TypeInt == 1); + m_aircraft->ccpmAngleY->setEnabled(TypeInt == 1); + m_aircraft->ccpmAngleZ->setEnabled(TypeInt == 1); + m_aircraft->ccpmCorrectionAngle->setEnabled(TypeInt != 0); - m_ccpm->ccpmServoWChannel->setEnabled(TypeInt>0); - m_ccpm->ccpmServoXChannel->setEnabled(TypeInt>0); - m_ccpm->ccpmServoYChannel->setEnabled(TypeInt>0); - m_ccpm->ccpmServoZChannel->setEnabled(TypeInt>0); - m_ccpm->ccpmSingleServo->setEnabled(TypeInt>1); + m_aircraft->ccpmServoWChannel->setEnabled(TypeInt > 0); + m_aircraft->ccpmServoXChannel->setEnabled(TypeInt > 0); + m_aircraft->ccpmServoYChannel->setEnabled(TypeInt > 0); + m_aircraft->ccpmServoZChannel->setEnabled(TypeInt > 0); + m_aircraft->ccpmSingleServo->setEnabled(TypeInt > 1); - m_ccpm->ccpmEngineChannel->setEnabled(TypeInt>0); - m_ccpm->ccpmTailChannel->setEnabled(TypeInt>0); - m_ccpm->ccpmCollectiveSlider->setEnabled(TypeInt>0); - m_ccpm->ccpmCollectivespinBox->setEnabled(TypeInt>0); - m_ccpm->ccpmRevoSlider->setEnabled(TypeInt>0); - m_ccpm->ccpmREVOspinBox->setEnabled(TypeInt>0); + m_aircraft->ccpmEngineChannel->setEnabled(TypeInt > 0); + m_aircraft->ccpmTailChannel->setEnabled(TypeInt > 0); + m_aircraft->ccpmCollectiveSlider->setEnabled(TypeInt > 0); + m_aircraft->ccpmCollectivespinBox->setEnabled(TypeInt > 0); + m_aircraft->ccpmRevoSlider->setEnabled(TypeInt > 0); + m_aircraft->ccpmREVOspinBox->setEnabled(TypeInt > 0); - AdjustmentAngle=SingleServoIndex*90; + AdjustmentAngle = SingleServoIndex * 90; - m_ccpm->PitchCurve->setVisible(1); + m_aircraft->PitchCurve->setVisible(1); - NumServosDefined=4; + NumServosDefined = 4; //set values for pre defined heli types - if (TypeText.compare(QString::fromUtf8("CCPM 2 Servo 90º"), Qt::CaseInsensitive)==0) - { - m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0); - m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90,360)); - m_ccpm->ccpmAngleY->setValue(0); - m_ccpm->ccpmAngleZ->setValue(0); - m_ccpm->ccpmAngleY->setEnabled(0); - m_ccpm->ccpmAngleZ->setEnabled(0); - m_ccpm->ccpmServoYChannel->setCurrentIndex(0); - m_ccpm->ccpmServoZChannel->setCurrentIndex(0); - m_ccpm->ccpmServoYChannel->setEnabled(0); - m_ccpm->ccpmServoZChannel->setEnabled(0); - NumServosDefined=2; + if (TypeText.compare(QString::fromUtf8("CCPM 2 Servo 90º"), Qt::CaseInsensitive) == 0) { + m_aircraft->ccpmAngleW->setValue(AdjustmentAngle + 0); + m_aircraft->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90, 360)); + m_aircraft->ccpmAngleY->setValue(0); + m_aircraft->ccpmAngleZ->setValue(0); + m_aircraft->ccpmAngleY->setEnabled(0); + m_aircraft->ccpmAngleZ->setEnabled(0); + m_aircraft->ccpmServoYChannel->setCurrentIndex(0); + m_aircraft->ccpmServoZChannel->setCurrentIndex(0); + m_aircraft->ccpmServoYChannel->setEnabled(0); + m_aircraft->ccpmServoZChannel->setEnabled(0); + NumServosDefined = 2; + } else if (TypeText.compare(QString::fromUtf8("CCPM 3 Servo 90º"), Qt::CaseInsensitive) == 0) { + m_aircraft->ccpmAngleW->setValue(AdjustmentAngle + 0); + m_aircraft->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90, 360)); + m_aircraft->ccpmAngleY->setValue(fmod(AdjustmentAngle + 180, 360)); + m_aircraft->ccpmAngleZ->setValue(0); + m_aircraft->ccpmAngleZ->setEnabled(0); + m_aircraft->ccpmServoZChannel->setCurrentIndex(0); + m_aircraft->ccpmServoZChannel->setEnabled(0); + NumServosDefined = 3; + } else if (TypeText.compare(QString::fromUtf8("CCPM 4 Servo 90º"), Qt::CaseInsensitive) == 0) { + m_aircraft->ccpmAngleW->setValue(AdjustmentAngle + 0); + m_aircraft->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90, 360)); + m_aircraft->ccpmAngleY->setValue(fmod(AdjustmentAngle + 180, 360)); + m_aircraft->ccpmAngleZ->setValue(fmod(AdjustmentAngle + 270, 360)); + m_aircraft->ccpmSingleServo->setEnabled(0); + m_aircraft->ccpmSingleServo->setCurrentIndex(0); + NumServosDefined = 4; + } else if (TypeText.compare(QString::fromUtf8("CCPM 3 Servo 120º"), Qt::CaseInsensitive) == 0) { + m_aircraft->ccpmAngleW->setValue(AdjustmentAngle + 0); + m_aircraft->ccpmAngleX->setValue(fmod(AdjustmentAngle + 120, 360)); + m_aircraft->ccpmAngleY->setValue(fmod(AdjustmentAngle + 240, 360)); + m_aircraft->ccpmAngleZ->setValue(0); + m_aircraft->ccpmAngleZ->setEnabled(0); + m_aircraft->ccpmServoZChannel->setCurrentIndex(0); + m_aircraft->ccpmServoZChannel->setEnabled(0); + NumServosDefined = 3; + } else if (TypeText.compare(QString::fromUtf8("CCPM 3 Servo 140º"), Qt::CaseInsensitive) == 0) { + m_aircraft->ccpmAngleW->setValue(AdjustmentAngle + 0); + m_aircraft->ccpmAngleX->setValue(fmod(AdjustmentAngle + 140, 360)); + m_aircraft->ccpmAngleY->setValue(fmod(AdjustmentAngle + 220, 360)); + m_aircraft->ccpmAngleZ->setValue(0); + m_aircraft->ccpmAngleZ->setEnabled(0); + m_aircraft->ccpmServoZChannel->setCurrentIndex(0); + m_aircraft->ccpmServoZChannel->setEnabled(0); + NumServosDefined = 3; + } else if (TypeText.compare(QString::fromUtf8("FP 2 Servo 90º"), Qt::CaseInsensitive) == 0) { + m_aircraft->ccpmAngleW->setValue(AdjustmentAngle + 0); + m_aircraft->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90, 360)); + m_aircraft->ccpmAngleY->setValue(0); + m_aircraft->ccpmAngleZ->setValue(0); + m_aircraft->ccpmAngleY->setEnabled(0); + m_aircraft->ccpmAngleZ->setEnabled(0); + m_aircraft->ccpmServoYChannel->setCurrentIndex(0); + m_aircraft->ccpmServoZChannel->setCurrentIndex(0); + m_aircraft->ccpmServoYChannel->setEnabled(0); + m_aircraft->ccpmServoZChannel->setEnabled(0); - } - else if (TypeText.compare(QString::fromUtf8("CCPM 3 Servo 90º"), Qt::CaseInsensitive)==0) - { - m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0); - m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90,360)); - m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 180,360)); - m_ccpm->ccpmAngleZ->setValue(0); - m_ccpm->ccpmAngleZ->setEnabled(0); - m_ccpm->ccpmServoZChannel->setCurrentIndex(0); - m_ccpm->ccpmServoZChannel->setEnabled(0); - NumServosDefined=3; - - } - else if (TypeText.compare(QString::fromUtf8("CCPM 4 Servo 90º"), Qt::CaseInsensitive)==0) - { - m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0); - m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90,360)); - m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 180,360)); - m_ccpm->ccpmAngleZ->setValue(fmod(AdjustmentAngle + 270,360)); - m_ccpm->ccpmSingleServo->setEnabled(0); - m_ccpm->ccpmSingleServo->setCurrentIndex(0); - NumServosDefined=4; - - } - else if (TypeText.compare(QString::fromUtf8("CCPM 3 Servo 120º"), Qt::CaseInsensitive)==0) - { - m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0); - m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 120,360)); - m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 240,360)); - m_ccpm->ccpmAngleZ->setValue(0); - m_ccpm->ccpmAngleZ->setEnabled(0); - m_ccpm->ccpmServoZChannel->setCurrentIndex(0); - m_ccpm->ccpmServoZChannel->setEnabled(0); - NumServosDefined=3; - - } - else if (TypeText.compare(QString::fromUtf8("CCPM 3 Servo 140º"), Qt::CaseInsensitive)==0) - { - m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0); - m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 140,360)); - m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 220,360)); - m_ccpm->ccpmAngleZ->setValue(0); - m_ccpm->ccpmAngleZ->setEnabled(0); - m_ccpm->ccpmServoZChannel->setCurrentIndex(0); - m_ccpm->ccpmServoZChannel->setEnabled(0); - NumServosDefined=3; - - } - else if (TypeText.compare(QString::fromUtf8("FP 2 Servo 90º"), Qt::CaseInsensitive)==0) - { - m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0); - m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90,360)); - m_ccpm->ccpmAngleY->setValue(0); - m_ccpm->ccpmAngleZ->setValue(0); - m_ccpm->ccpmAngleY->setEnabled(0); - m_ccpm->ccpmAngleZ->setEnabled(0); - m_ccpm->ccpmServoYChannel->setCurrentIndex(0); - m_ccpm->ccpmServoZChannel->setCurrentIndex(0); - m_ccpm->ccpmServoYChannel->setEnabled(0); - m_ccpm->ccpmServoZChannel->setEnabled(0); - - m_ccpm->ccpmCollectivespinBox->setEnabled(0); - m_ccpm->ccpmCollectiveSlider->setEnabled(0); - m_ccpm->ccpmCollectivespinBox->setValue(0); - m_ccpm->ccpmCollectiveSlider->setValue(0); - m_ccpm->PitchCurve->setVisible(0); - NumServosDefined=2; - } - else if (TypeText.compare(QString::fromUtf8("Coax 2 Servo 90º"), Qt::CaseInsensitive)==0) - { - m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0); - m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90,360)); - m_ccpm->ccpmAngleY->setValue(0); - m_ccpm->ccpmAngleZ->setValue(0); - m_ccpm->ccpmAngleY->setEnabled(0); - m_ccpm->ccpmAngleZ->setEnabled(0); - m_ccpm->ccpmServoYChannel->setCurrentIndex(0); - m_ccpm->ccpmServoZChannel->setCurrentIndex(0); - m_ccpm->ccpmServoYChannel->setEnabled(0); - m_ccpm->ccpmServoZChannel->setEnabled(0); - - m_ccpm->ccpmCollectivespinBox->setEnabled(0); - m_ccpm->ccpmCollectiveSlider->setEnabled(0); - m_ccpm->ccpmCollectivespinBox->setValue(0); - m_ccpm->ccpmCollectiveSlider->setValue(0); - m_ccpm->PitchCurve->setVisible(0); - NumServosDefined=2; + m_aircraft->ccpmCollectivespinBox->setEnabled(0); + m_aircraft->ccpmCollectiveSlider->setEnabled(0); + m_aircraft->ccpmCollectivespinBox->setValue(0); + m_aircraft->ccpmCollectiveSlider->setValue(0); + m_aircraft->PitchCurve->setVisible(0); + NumServosDefined = 2; + } else if (TypeText.compare(QString::fromUtf8("Coax 2 Servo 90º"), Qt::CaseInsensitive) == 0) { + m_aircraft->ccpmAngleW->setValue(AdjustmentAngle + 0); + m_aircraft->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90, 360)); + m_aircraft->ccpmAngleY->setValue(0); + m_aircraft->ccpmAngleZ->setValue(0); + m_aircraft->ccpmAngleY->setEnabled(0); + m_aircraft->ccpmAngleZ->setEnabled(0); + m_aircraft->ccpmServoYChannel->setCurrentIndex(0); + m_aircraft->ccpmServoZChannel->setCurrentIndex(0); + m_aircraft->ccpmServoYChannel->setEnabled(0); + m_aircraft->ccpmServoZChannel->setEnabled(0); + m_aircraft->ccpmCollectivespinBox->setEnabled(0); + m_aircraft->ccpmCollectiveSlider->setEnabled(0); + m_aircraft->ccpmCollectivespinBox->setValue(0); + m_aircraft->ccpmCollectiveSlider->setValue(0); + m_aircraft->PitchCurve->setVisible(0); + NumServosDefined = 2; } //Set the text of the motor boxes - if (TypeText.compare(QString::fromUtf8("Coax 2 Servo 90º"), Qt::CaseInsensitive)==0) - { - m_ccpm->ccpmEngineLabel->setText("CW motor"); - m_ccpm->ccpmTailLabel->setText("CCW motor"); - } - else{ - m_ccpm->ccpmEngineLabel->setText("Engine"); - m_ccpm->ccpmTailLabel->setText("Tail rotor"); + if (TypeText.compare(QString::fromUtf8("Coax 2 Servo 90º"), Qt::CaseInsensitive) == 0) { + m_aircraft->ccpmEngineLabel->setText("CW motor"); + m_aircraft->ccpmTailLabel->setText("CCW motor"); + } else { + m_aircraft->ccpmEngineLabel->setText("Engine"); + m_aircraft->ccpmTailLabel->setText("Tail rotor"); } //set the visibility of the swashplate servo selection boxes - m_ccpm->ccpmServoWLabel->setVisible(NumServosDefined>=1); - m_ccpm->ccpmServoXLabel->setVisible(NumServosDefined>=2); - m_ccpm->ccpmServoYLabel->setVisible(NumServosDefined>=3); - m_ccpm->ccpmServoZLabel->setVisible(NumServosDefined>=4); - m_ccpm->ccpmServoWChannel->setVisible(NumServosDefined>=1); - m_ccpm->ccpmServoXChannel->setVisible(NumServosDefined>=2); - m_ccpm->ccpmServoYChannel->setVisible(NumServosDefined>=3); - m_ccpm->ccpmServoZChannel->setVisible(NumServosDefined>=4); - - //set the visibility of the swashplate angle selection boxes - m_ccpm->ccpmServoWLabel_2->setVisible(NumServosDefined>=1); - m_ccpm->ccpmServoXLabel_2->setVisible(NumServosDefined>=2); - m_ccpm->ccpmServoYLabel_2->setVisible(NumServosDefined>=3); - m_ccpm->ccpmServoZLabel_2->setVisible(NumServosDefined>=4); - m_ccpm->ccpmAngleW->setVisible(NumServosDefined>=1); - m_ccpm->ccpmAngleX->setVisible(NumServosDefined>=2); - m_ccpm->ccpmAngleY->setVisible(NumServosDefined>=3); - m_ccpm->ccpmAngleZ->setVisible(NumServosDefined>=4); - + m_aircraft->ccpmServoWLabel->setVisible(NumServosDefined >= 1); + m_aircraft->ccpmServoXLabel->setVisible(NumServosDefined >= 2); + m_aircraft->ccpmServoYLabel->setVisible(NumServosDefined >= 3); + m_aircraft->ccpmServoZLabel->setVisible(NumServosDefined >= 4); + m_aircraft->ccpmServoWChannel->setVisible(NumServosDefined >= 1); + m_aircraft->ccpmServoXChannel->setVisible(NumServosDefined >= 2); + m_aircraft->ccpmServoYChannel->setVisible(NumServosDefined >= 3); + m_aircraft->ccpmServoZChannel->setVisible(NumServosDefined >= 4); - m_ccpm->ccpmAdvancedSettingsTable->resizeColumnsToContents(); - for (int i=0;i<6;i++) { - m_ccpm->ccpmAdvancedSettingsTable->setColumnWidth(i,(m_ccpm->ccpmAdvancedSettingsTable->width()- - m_ccpm->ccpmAdvancedSettingsTable->verticalHeader()->width())/6); + //set the visibility of the swashplate angle selection boxes + m_aircraft->ccpmServoWLabel_2->setVisible(NumServosDefined >= 1); + m_aircraft->ccpmServoXLabel_2->setVisible(NumServosDefined >= 2); + m_aircraft->ccpmServoYLabel_2->setVisible(NumServosDefined >= 3); + m_aircraft->ccpmServoZLabel_2->setVisible(NumServosDefined >= 4); + m_aircraft->ccpmAngleW->setVisible(NumServosDefined >= 1); + m_aircraft->ccpmAngleX->setVisible(NumServosDefined >= 2); + m_aircraft->ccpmAngleY->setVisible(NumServosDefined >= 3); + m_aircraft->ccpmAngleZ->setVisible(NumServosDefined >= 4); + + QTableWidget *table = m_aircraft->ccpmAdvancedSettingsTable; + table->resizeColumnsToContents(); + for (int i = 0; i < 6; i++) { + table->setColumnWidth(i, (table->width() - table->verticalHeader()->width()) / 6); } //update UI ccpmSwashplateUpdate(); - } - - void ConfigCcpmWidget::ccpmSwashplateRedraw() { double angle[CCPM_MAX_SWASH_SERVOS],CorrectionAngle,x,y,w,h,radius,CenterX,CenterY; @@ -483,25 +550,25 @@ void ConfigCcpmWidget::ccpmSwashplateRedraw() double scale,xscale,yscale; - size = m_ccpm->SwashplateImage->rect(); + size = m_aircraft->SwashplateImage->rect(); xscale=size.width(); yscale=size.height(); scale=xscale; if (yscaleSwashplateImage->resetTransform (); - m_ccpm->SwashplateImage->scale(scale,scale); + m_aircraft->SwashplateImage->resetTransform (); + m_aircraft->SwashplateImage->scale(scale,scale); - size = m_ccpm->SwashLvlSwashplateImage->rect(); + size = m_aircraft->SwashLvlSwashplateImage->rect(); xscale=size.width(); yscale=size.height(); scale=xscale; if (yscaleSwashLvlSwashplateImage->resetTransform (); - m_ccpm->SwashLvlSwashplateImage->scale(scale,scale); + m_aircraft->SwashLvlSwashplateImage->resetTransform (); + m_aircraft->SwashLvlSwashplateImage->scale(scale,scale); - CorrectionAngle=m_ccpm->ccpmCorrectionAngle->value(); + CorrectionAngle=m_aircraft->ccpmCorrectionAngle->value(); CenterX=200; CenterY=200; @@ -510,18 +577,18 @@ void ConfigCcpmWidget::ccpmSwashplateRedraw() SwashplateImg->setPos(CenterX-bounds.width()/2,CenterY-bounds.height()/2); - defined[0]=(m_ccpm->ccpmServoWChannel->isEnabled()); - defined[1]=(m_ccpm->ccpmServoXChannel->isEnabled()); - defined[2]=(m_ccpm->ccpmServoYChannel->isEnabled()); - defined[3]=(m_ccpm->ccpmServoZChannel->isEnabled()); - used[0]=((m_ccpm->ccpmServoWChannel->currentIndex()>0)&&(m_ccpm->ccpmServoWChannel->isEnabled())); - used[1]=((m_ccpm->ccpmServoXChannel->currentIndex()>0)&&(m_ccpm->ccpmServoXChannel->isEnabled())); - used[2]=((m_ccpm->ccpmServoYChannel->currentIndex()>0)&&(m_ccpm->ccpmServoYChannel->isEnabled())); - used[3]=((m_ccpm->ccpmServoZChannel->currentIndex()>0)&&(m_ccpm->ccpmServoZChannel->isEnabled())); - angle[0]=(CorrectionAngle+180+m_ccpm->ccpmAngleW->value())*Pi/180.00; - angle[1]=(CorrectionAngle+180+m_ccpm->ccpmAngleX->value())*Pi/180.00; - angle[2]=(CorrectionAngle+180+m_ccpm->ccpmAngleY->value())*Pi/180.00; - angle[3]=(CorrectionAngle+180+m_ccpm->ccpmAngleZ->value())*Pi/180.00; + defined[0]=(m_aircraft->ccpmServoWChannel->isEnabled()); + defined[1]=(m_aircraft->ccpmServoXChannel->isEnabled()); + defined[2]=(m_aircraft->ccpmServoYChannel->isEnabled()); + defined[3]=(m_aircraft->ccpmServoZChannel->isEnabled()); + used[0]=((m_aircraft->ccpmServoWChannel->currentIndex()>0)&&(m_aircraft->ccpmServoWChannel->isEnabled())); + used[1]=((m_aircraft->ccpmServoXChannel->currentIndex()>0)&&(m_aircraft->ccpmServoXChannel->isEnabled())); + used[2]=((m_aircraft->ccpmServoYChannel->currentIndex()>0)&&(m_aircraft->ccpmServoYChannel->isEnabled())); + used[3]=((m_aircraft->ccpmServoZChannel->currentIndex()>0)&&(m_aircraft->ccpmServoZChannel->isEnabled())); + angle[0]=(CorrectionAngle+180+m_aircraft->ccpmAngleW->value())*Pi/180.00; + angle[1]=(CorrectionAngle+180+m_aircraft->ccpmAngleX->value())*Pi/180.00; + angle[2]=(CorrectionAngle+180+m_aircraft->ccpmAngleY->value())*Pi/180.00; + angle[3]=(CorrectionAngle+180+m_aircraft->ccpmAngleZ->value())*Pi/180.00; for (i=0;imove(m_ccpm->SwashLvlSwashplateImage->mapFromScene (x, y)); + SwashLvlSpinBoxes[i]->move(m_aircraft->SwashLvlSwashplateImage->mapFromScene (x, y)); SwashLvlSpinBoxes[i]->setVisible(used[i]!=0); radius=220; @@ -570,9 +637,9 @@ void ConfigCcpmWidget::ccpmSwashplateRedraw() ServoLines[i]->setVisible(defined[i]!=0); } - //m_ccpm->SwashplateImage->centerOn (CenterX, CenterY); + //m_aircraft->SwashplateImage->centerOn (CenterX, CenterY); - //m_ccpm->SwashplateImage->fitInView(SwashplateImg, Qt::KeepAspectRatio); + //m_aircraft->SwashplateImage->fitInView(SwashplateImg, Qt::KeepAspectRatio); } void ConfigCcpmWidget::ccpmSwashplateUpdate() @@ -586,132 +653,142 @@ void ConfigCcpmWidget::UpdateMixer() { bool useCCPM; bool useCyclic; - int i,j,ThisEnable[6]; - float CollectiveConstant,PitchConstant,RollConstant,ThisAngle[6]; + int ThisEnable[6]; + float CollectiveConstant, PitchConstant, RollConstant; + float ThisAngle[6]; QString Channel; if (throwConfigError(QString("HeliCP"))) return; - GUIConfigDataUnion config = GetConfigData(); + GUIConfigDataUnion config = getConfigData(); useCCPM = !(config.heli.ccpmCollectivePassthroughState || !config.heli.ccpmLinkCyclicState); useCyclic = config.heli.ccpmLinkRollState; - CollectiveConstant = (float)config.heli.SliderValue0 / 100.00; + CollectiveConstant = (float) config.heli.SliderValue0 / 100.00; - if (useCCPM) - {//cyclic = 1 - collective - PitchConstant = 1-CollectiveConstant; + if (useCCPM) { //cyclic = 1 - collective + PitchConstant = 1 - CollectiveConstant; RollConstant = PitchConstant; - } - else - { - PitchConstant = (float)config.heli.SliderValue1 / 100.00;; - if (useCyclic) - { + } else { + PitchConstant = (float) config.heli.SliderValue1 / 100.00; + ; + if (useCyclic) { RollConstant = PitchConstant; - } - else - { - RollConstant = (float)config.heli.SliderValue2 / 100.00;; - } + } else { + RollConstant = (float) config.heli.SliderValue2 / 100.00; + ; + } } - if (config.heli.SwashplateType>0) - {//not advanced settings - //get the channel data from the ui - MixerChannelData[0] = m_ccpm->ccpmEngineChannel->currentIndex(); - MixerChannelData[1] = m_ccpm->ccpmTailChannel->currentIndex(); - MixerChannelData[2] = m_ccpm->ccpmServoWChannel->currentIndex(); - MixerChannelData[3] = m_ccpm->ccpmServoXChannel->currentIndex(); - MixerChannelData[4] = m_ccpm->ccpmServoYChannel->currentIndex(); - MixerChannelData[5] = m_ccpm->ccpmServoZChannel->currentIndex(); + if (config.heli.SwashplateType > 0) { //not advanced settings + //get the channel data from the ui + MixerChannelData[0] = m_aircraft->ccpmEngineChannel->currentIndex(); + MixerChannelData[1] = m_aircraft->ccpmTailChannel->currentIndex(); + MixerChannelData[2] = m_aircraft->ccpmServoWChannel->currentIndex(); + MixerChannelData[3] = m_aircraft->ccpmServoXChannel->currentIndex(); + MixerChannelData[4] = m_aircraft->ccpmServoYChannel->currentIndex(); + MixerChannelData[5] = m_aircraft->ccpmServoZChannel->currentIndex(); //get the angle data from the ui - ThisAngle[2] = m_ccpm->ccpmAngleW->value(); - ThisAngle[3] = m_ccpm->ccpmAngleX->value(); - ThisAngle[4] = m_ccpm->ccpmAngleY->value(); - ThisAngle[5] = m_ccpm->ccpmAngleZ->value(); + ThisAngle[2] = m_aircraft->ccpmAngleW->value(); + ThisAngle[3] = m_aircraft->ccpmAngleX->value(); + ThisAngle[4] = m_aircraft->ccpmAngleY->value(); + ThisAngle[5] = m_aircraft->ccpmAngleZ->value(); //get the angle data from the ui - ThisEnable[2] = m_ccpm->ccpmServoWChannel->isEnabled(); - ThisEnable[3] = m_ccpm->ccpmServoXChannel->isEnabled(); - ThisEnable[4] = m_ccpm->ccpmServoYChannel->isEnabled(); - ThisEnable[5] = m_ccpm->ccpmServoZChannel->isEnabled(); - - ServosText[0]->setPlainText(QString("%1").arg( MixerChannelData[2] )); - ServosText[1]->setPlainText(QString("%1").arg( MixerChannelData[3] )); - ServosText[2]->setPlainText(QString("%1").arg( MixerChannelData[4] )); - ServosText[3]->setPlainText(QString("%1").arg( MixerChannelData[5] )); + ThisEnable[2] = m_aircraft->ccpmServoWChannel->isEnabled(); + ThisEnable[3] = m_aircraft->ccpmServoXChannel->isEnabled(); + ThisEnable[4] = m_aircraft->ccpmServoYChannel->isEnabled(); + ThisEnable[5] = m_aircraft->ccpmServoZChannel->isEnabled(); + ServosText[0]->setPlainText(QString("%1").arg(MixerChannelData[2])); + ServosText[1]->setPlainText(QString("%1").arg(MixerChannelData[3])); + ServosText[2]->setPlainText(QString("%1").arg(MixerChannelData[4])); + ServosText[3]->setPlainText(QString("%1").arg(MixerChannelData[5])); //go through the user data and update the mixer matrix - for (i=0;i<6;i++) - { - if ((MixerChannelData[i]>0) && ((ThisEnable[i])||(i<2))) - { - m_ccpm->ccpmAdvancedSettingsTable->item(i,0)->setText(QString("%1").arg( MixerChannelData[i] )); + QTableWidget *table = m_aircraft->ccpmAdvancedSettingsTable; + for (int i = 0; i < 6; i++) { + if ((MixerChannelData[i] > 0) && ((ThisEnable[i]) || (i < 2))) { + table->item(i, 0)->setText(QString("%1").arg(MixerChannelData[i])); //Generate the mixer vector - if (i==0) - {//main motor-engine - m_ccpm->ccpmAdvancedSettingsTable->item(i,1)->setText(QString("%1").arg(127));//ThrottleCurve1 - m_ccpm->ccpmAdvancedSettingsTable->item(i,2)->setText(QString("%1").arg(0));//ThrottleCurve2 - m_ccpm->ccpmAdvancedSettingsTable->item(i,3)->setText(QString("%1").arg(0));//Roll - m_ccpm->ccpmAdvancedSettingsTable->item(i,4)->setText(QString("%1").arg(0));//Pitch + if (i == 0) { //main motor-engine + table->item(i, 1)->setText(QString("%1").arg(127)); //ThrottleCurve1 + table->item(i, 2)->setText(QString("%1").arg(0)); //ThrottleCurve2 + table->item(i, 3)->setText(QString("%1").arg(0)); //Roll + table->item(i, 4)->setText(QString("%1").arg(0)); //Pitch - if (TypeText.compare(QString::fromUtf8("Coax 2 Servo 90º"), Qt::CaseInsensitive)==0) - m_ccpm->ccpmAdvancedSettingsTable->item(i,5)->setText(QString("%1").arg(-127));//Yaw - else - m_ccpm->ccpmAdvancedSettingsTable->item(i,5)->setText(QString("%1").arg(0));//Yaw - - } - if (i==1) - {//tailrotor --or-- counter-clockwise motor - if (TypeText.compare(QString::fromUtf8("Coax 2 Servo 90º"), Qt::CaseInsensitive)==0) - { - m_ccpm->ccpmAdvancedSettingsTable->item(i,1)->setText(QString("%1").arg(127));//ThrottleCurve1 - m_ccpm->ccpmAdvancedSettingsTable->item(i,5)->setText(QString("%1").arg(127));//Yaw - } - else{ - m_ccpm->ccpmAdvancedSettingsTable->item(i,1)->setText(QString("%1").arg(0));//ThrottleCurve1 - m_ccpm->ccpmAdvancedSettingsTable->item(i,5)->setText(QString("%1").arg(127));//Yaw + if (TypeText.compare(QString::fromUtf8("Coax 2 Servo 90º"), Qt::CaseInsensitive) == 0) { + // Yaw + table->item(i, 5)->setText(QString("%1").arg(-127)); + } else { + // Yaw + table->item(i, 5)->setText(QString("%1").arg(0)); } - m_ccpm->ccpmAdvancedSettingsTable->item(i,2)->setText(QString("%1").arg(0));//ThrottleCurve2 - m_ccpm->ccpmAdvancedSettingsTable->item(i,3)->setText(QString("%1").arg(0));//Roll - m_ccpm->ccpmAdvancedSettingsTable->item(i,4)->setText(QString("%1").arg(0));//Pitch + } + if (i == 1) { + // tailrotor --or-- counter-clockwise motor + if (TypeText.compare(QString::fromUtf8("Coax 2 Servo 90º"), Qt::CaseInsensitive) == 0) { + // ThrottleCurve1 + table->item(i, 1)->setText(QString("%1").arg(127)); + // Yaw + table->item(i, 5)->setText(QString("%1").arg(127)); + } else { + // ThrottleCurve1 + table->item(i, 1)->setText(QString("%1").arg(0)); + // Yaw + table->item(i, 5)->setText(QString("%1").arg(127)); + } + //ThrottleCurve2 + table->item(i, 2)->setText(QString("%1").arg(0)); + // Roll + table->item(i, 3)->setText(QString("%1").arg(0)); + // Pitch + table->item(i, 4)->setText(QString("%1").arg(0)); } - if (i>1) - {//Swashplate - m_ccpm->ccpmAdvancedSettingsTable->item(i,1)->setText(QString("%1").arg(0));//ThrottleCurve1 - m_ccpm->ccpmAdvancedSettingsTable->item(i,2)->setText(QString("%1").arg((int)(127.0*CollectiveConstant)));//ThrottleCurve2 - m_ccpm->ccpmAdvancedSettingsTable->item(i,3)->setText(QString("%1").arg((int)(127.0*(RollConstant)*sin((180+config.heli.CorrectionAngle + ThisAngle[i])*Pi/180.00))));//Roll - m_ccpm->ccpmAdvancedSettingsTable->item(i,4)->setText(QString("%1").arg((int)(127.0*(PitchConstant)*cos((config.heli.CorrectionAngle + ThisAngle[i])*Pi/180.00))));//Pitch - m_ccpm->ccpmAdvancedSettingsTable->item(i,5)->setText(QString("%1").arg(0));//Yaw + if (i > 1) { + // Swashplate + //ThrottleCurve1 + table->item(i, 1)->setText(QString("%1").arg(0)); + //ThrottleCurve2 + table->item(i, 2)->setText(QString("%1").arg((int) (127.0 * CollectiveConstant))); + table->item(i, 3)->setText( + QString("%1").arg( + (int) (127.0 * (RollConstant) + * sin((180 + config.heli.CorrectionAngle + ThisAngle[i]) * Pi / 180.00)))); //Roll + table->item(i, 4)->setText( + QString("%1").arg( + (int) (127.0 * (PitchConstant) + * cos((config.heli.CorrectionAngle + ThisAngle[i]) * Pi / 180.00)))); //Pitch + // Yaw + table->item(i, 5)->setText(QString("%1").arg(0)); } - } - else - { - for (j=0;j<6;j++) m_ccpm->ccpmAdvancedSettingsTable->item(i,j)->setText(QString("-")); + } else { + for (int j = 0; j < 6; j++) { + table->item(i, j)->setText(QString("-")); + } } } + } else { + // advanced settings + QTableWidget *table = m_aircraft->ccpmAdvancedSettingsTable; + for (int i = 0; i < 6; i++) { + Channel = table->item(i, 0)->text(); + if (Channel == "-") { + Channel = QString("9"); + } + MixerChannelData[i] = Channel.toInt(); + } } - else - {//advanced settings - for (i=0;i<6;i++) - { - Channel =m_ccpm->ccpmAdvancedSettingsTable->item(i,0)->text(); - if (Channel == "-") Channel = QString("9"); - MixerChannelData[i]= Channel.toInt(); - } - } - } + QString ConfigCcpmWidget::updateConfigObjects() { QString airframeType = "HeliCP"; @@ -719,145 +796,86 @@ QString ConfigCcpmWidget::updateConfigObjects() bool useCCPM; bool useCyclic; - if (updatingFromHardware == TRUE) return airframeType; + if (updatingFromHardware == TRUE) + return airframeType; updatingFromHardware = TRUE; //get the user options - GUIConfigDataUnion config = GetConfigData(); + GUIConfigDataUnion config = getConfigData(); //swashplate config - config.heli.SwashplateType = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex()-1; - config.heli.FirstServoIndex = m_ccpm->ccpmSingleServo->currentIndex(); + config.heli.SwashplateType = m_aircraft->ccpmType->count() - m_aircraft->ccpmType->currentIndex() - 1; + config.heli.FirstServoIndex = m_aircraft->ccpmSingleServo->currentIndex(); //ccpm mixing options - config.heli.ccpmCollectivePassthroughState = m_ccpm->ccpmCollectivePassthrough->isChecked(); - config.heli.ccpmLinkCyclicState = m_ccpm->ccpmLinkCyclic->isChecked(); - config.heli.ccpmLinkRollState = m_ccpm->ccpmLinkRoll->isChecked(); + config.heli.ccpmCollectivePassthroughState = m_aircraft->ccpmCollectivePassthrough->isChecked(); + config.heli.ccpmLinkCyclicState = m_aircraft->ccpmLinkCyclic->isChecked(); + config.heli.ccpmLinkRollState = m_aircraft->ccpmLinkRoll->isChecked(); useCCPM = !(config.heli.ccpmCollectivePassthroughState || !config.heli.ccpmLinkCyclicState); useCyclic = config.heli.ccpmLinkRollState; //correction angle - config.heli.CorrectionAngle = m_ccpm->ccpmCorrectionAngle->value(); + config.heli.CorrectionAngle = m_aircraft->ccpmCorrectionAngle->value(); //update sliders - if (useCCPM) - { - config.heli.SliderValue0 = m_ccpm->ccpmCollectiveSlider->value(); + if (useCCPM) { + config.heli.SliderValue0 = m_aircraft->ccpmCollectiveSlider->value(); + } else { + config.heli.SliderValue0 = m_aircraft->ccpmCollectiveScale->value(); } - else - { - config.heli.SliderValue0 = m_ccpm->ccpmCollectiveScale->value(); + if (useCyclic) { + config.heli.SliderValue1 = m_aircraft->ccpmCyclicScale->value(); + } else { + config.heli.SliderValue1 = m_aircraft->ccpmPitchScale->value(); } - if (useCyclic) - { - config.heli.SliderValue1 = m_ccpm->ccpmCyclicScale->value(); - } - else - { - config.heli.SliderValue1 = m_ccpm->ccpmPitchScale->value(); - } - config.heli.SliderValue2 = m_ccpm->ccpmRollScale->value(); + config.heli.SliderValue2 = m_aircraft->ccpmRollScale->value(); //servo assignments - config.heli.ServoIndexW = m_ccpm->ccpmServoWChannel->currentIndex(); - config.heli.ServoIndexX = m_ccpm->ccpmServoXChannel->currentIndex(); - config.heli.ServoIndexY = m_ccpm->ccpmServoYChannel->currentIndex(); - config.heli.ServoIndexZ = m_ccpm->ccpmServoZChannel->currentIndex(); + config.heli.ServoIndexW = m_aircraft->ccpmServoWChannel->currentIndex(); + config.heli.ServoIndexX = m_aircraft->ccpmServoXChannel->currentIndex(); + config.heli.ServoIndexY = m_aircraft->ccpmServoYChannel->currentIndex(); + config.heli.ServoIndexZ = m_aircraft->ccpmServoZChannel->currentIndex(); //throttle - config.heli.Throttle = m_ccpm->ccpmEngineChannel->currentIndex(); + config.heli.Throttle = m_aircraft->ccpmEngineChannel->currentIndex(); //tail - config.heli.Tail = m_ccpm->ccpmTailChannel->currentIndex(); + config.heli.Tail = m_aircraft->ccpmTailChannel->currentIndex(); - SetConfigData(config); + setConfigData(config); updatingFromHardware = FALSE; return airframeType; } -QString ConfigCcpmWidget::updateConfigObjectsFromWidgets() //UpdateCCPMOptionsFromUI() -{ - QString airframeType = updateConfigObjects(); - - setMixer(); - - return airframeType; -} - -void ConfigCcpmWidget::refreshWidgetsValues(QString frameType) //UpdateCCPMUIFromOptions() -{ - Q_UNUSED(frameType); - - GUIConfigDataUnion config = GetConfigData(); - - //swashplate config - setComboCurrentIndex( m_ccpm->ccpmType, m_ccpm->ccpmType->count() - (config.heli.SwashplateType +1)); - setComboCurrentIndex(m_ccpm->ccpmSingleServo, config.heli.FirstServoIndex); - - //ccpm mixing options - m_ccpm->ccpmCollectivePassthrough->setChecked(config.heli.ccpmCollectivePassthroughState); - m_ccpm->ccpmLinkCyclic->setChecked(config.heli.ccpmLinkCyclicState); - m_ccpm->ccpmLinkRoll->setChecked(config.heli.ccpmLinkRollState); - - //correction angle - m_ccpm->ccpmCorrectionAngle->setValue(config.heli.CorrectionAngle); - - //update sliders - m_ccpm->ccpmCollectiveScale->setValue(config.heli.SliderValue0); - m_ccpm->ccpmCollectiveScaleBox->setValue(config.heli.SliderValue0); - m_ccpm->ccpmCyclicScale->setValue(config.heli.SliderValue1); - m_ccpm->ccpmCyclicScaleBox->setValue(config.heli.SliderValue1); - m_ccpm->ccpmPitchScale->setValue(config.heli.SliderValue1); - m_ccpm->ccpmPitchScaleBox->setValue(config.heli.SliderValue1); - m_ccpm->ccpmRollScale->setValue(config.heli.SliderValue2); - m_ccpm->ccpmRollScaleBox->setValue(config.heli.SliderValue2); - m_ccpm->ccpmCollectiveSlider->setValue(config.heli.SliderValue0); - m_ccpm->ccpmCollectivespinBox->setValue(config.heli.SliderValue0); - - //servo assignments - setComboCurrentIndex(m_ccpm->ccpmServoWChannel, config.heli.ServoIndexW); - setComboCurrentIndex( m_ccpm->ccpmServoXChannel,config.heli.ServoIndexX); - setComboCurrentIndex( m_ccpm->ccpmServoYChannel,config.heli.ServoIndexY); - setComboCurrentIndex( m_ccpm->ccpmServoZChannel,config.heli.ServoIndexZ); - - //throttle - setComboCurrentIndex( m_ccpm->ccpmEngineChannel, config.heli.Throttle); - //tail - setComboCurrentIndex( m_ccpm->ccpmTailChannel, config.heli.Tail); - - getMixer(); -} - - void ConfigCcpmWidget::SetUIComponentVisibilities() { - m_ccpm->ccpmRevoMixingBox->setVisible(0); - - m_ccpm->ccpmPitchMixingBox->setVisible(!m_ccpm->ccpmCollectivePassthrough->isChecked() && - m_ccpm->ccpmLinkCyclic->isChecked()); + m_aircraft->ccpmRevoMixingBox->setVisible(0); - m_ccpm->ccpmCollectiveScalingBox->setVisible(m_ccpm->ccpmCollectivePassthrough->isChecked() || !m_ccpm->ccpmLinkCyclic->isChecked()); + m_aircraft->ccpmPitchMixingBox->setVisible( + !m_aircraft->ccpmCollectivePassthrough->isChecked() && m_aircraft->ccpmLinkCyclic->isChecked()); - m_ccpm->ccpmLinkCyclic->setVisible(!m_ccpm->ccpmCollectivePassthrough->isChecked()); + m_aircraft->ccpmCollectiveScalingBox->setVisible( + m_aircraft->ccpmCollectivePassthrough->isChecked() || !m_aircraft->ccpmLinkCyclic->isChecked()); - m_ccpm->ccpmCyclicScalingBox->setVisible((m_ccpm->ccpmCollectivePassthrough->isChecked() || !m_ccpm->ccpmLinkCyclic->isChecked()) && - m_ccpm->ccpmLinkRoll->isChecked()); + m_aircraft->ccpmLinkCyclic->setVisible(!m_aircraft->ccpmCollectivePassthrough->isChecked()); - if (!m_ccpm->ccpmCollectivePassthrough->checkState() && m_ccpm->ccpmLinkCyclic->isChecked()) - { - m_ccpm->ccpmPitchScalingBox->setVisible(0); - m_ccpm->ccpmRollScalingBox->setVisible(0); - m_ccpm->ccpmLinkRoll->setVisible(0); + m_aircraft->ccpmCyclicScalingBox->setVisible( + (m_aircraft->ccpmCollectivePassthrough->isChecked() || !m_aircraft->ccpmLinkCyclic->isChecked()) + && m_aircraft->ccpmLinkRoll->isChecked()); - } - else - { - m_ccpm->ccpmPitchScalingBox->setVisible(!m_ccpm->ccpmLinkRoll->isChecked()); - m_ccpm->ccpmRollScalingBox->setVisible(!m_ccpm->ccpmLinkRoll->isChecked()); - m_ccpm->ccpmLinkRoll->setVisible(1); + if (!m_aircraft->ccpmCollectivePassthrough->checkState() && m_aircraft->ccpmLinkCyclic->isChecked()) { + m_aircraft->ccpmPitchScalingBox->setVisible(0); + m_aircraft->ccpmRollScalingBox->setVisible(0); + m_aircraft->ccpmLinkRoll->setVisible(0); + + } else { + m_aircraft->ccpmPitchScalingBox->setVisible(!m_aircraft->ccpmLinkRoll->isChecked()); + m_aircraft->ccpmRollScalingBox->setVisible(!m_aircraft->ccpmLinkRoll->isChecked()); + m_aircraft->ccpmLinkRoll->setVisible(1); } } + /** Request the current value of the SystemSettings which holds the ccpm type */ @@ -866,32 +884,29 @@ void ConfigCcpmWidget::getMixer() if (SwashLvlConfigurationInProgress)return; if (updatingToHardware)return; - updatingFromHardware=TRUE; + updatingFromHardware = TRUE; UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); - QPointer vconfig = new VehicleConfig(); - QList curveValues; - vconfig->getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, &curveValues); + getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, &curveValues); // is at least one of the curve values != 0? - if (vconfig->isValidThrottleCurve(&curveValues)) { - m_ccpm->ThrottleCurve->setCurve(&curveValues); + if (isValidThrottleCurve(&curveValues)) { + m_aircraft->ThrottleCurve->setCurve(&curveValues); } else { - m_ccpm->ThrottleCurve->ResetCurve(); + m_aircraft->ThrottleCurve->ResetCurve(); } - - vconfig->getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, &curveValues); + getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, &curveValues); // is at least one of the curve values != 0? - if (vconfig->isValidThrottleCurve(&curveValues)) { - m_ccpm->PitchCurve->setCurve(&curveValues); + if (isValidThrottleCurve(&curveValues)) { + m_aircraft->PitchCurve->setCurve(&curveValues); } else { - m_ccpm->PitchCurve->ResetCurve(); + m_aircraft->PitchCurve->ResetCurve(); } updatingFromHardware=FALSE; @@ -899,7 +914,6 @@ void ConfigCcpmWidget::getMixer() ccpmSwashplateUpdate(); } - /** Sends the config to the board (ccpm type) */ @@ -964,13 +978,13 @@ void ConfigCcpmWidget::setMixer() //Configure the vector for (j=0;j<5;j++) - mixers[MixerChannelData[i] - 1][j] = m_ccpm->ccpmAdvancedSettingsTable->item(i,j+1)->text().toInt(); + mixers[MixerChannelData[i] - 1][j] = m_aircraft->ccpmAdvancedSettingsTable->item(i,j+1)->text().toInt(); } } //get the user data for the curve into the mixer settings - QList curve1 = m_ccpm->ThrottleCurve->getCurve(); - QList curve2 = m_ccpm->PitchCurve->getCurve(); + QList curve1 = m_aircraft->ThrottleCurve->getCurve(); + QList curve2 = m_aircraft->PitchCurve->getCurve(); for (i=0;i<5;i++) { mixerSettingsData.ThrottleCurve1[i] = curve1.at(i); mixerSettingsData.ThrottleCurve2[i] = curve2.at(i); @@ -979,7 +993,7 @@ void ConfigCcpmWidget::setMixer() //mapping of collective input to curve 2... //MixerSettings.Curve2Source = Throttle,Roll,Pitch,Yaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5 //check if we are using throttle or directly from a channel... - if (m_ccpm->ccpmCollectivePassthrough->isChecked()) + if (m_aircraft->ccpmCollectivePassthrough->isChecked()) mixerSettingsData.Curve2Source = MixerSettings::CURVE2SOURCE_COLLECTIVE; else mixerSettingsData.Curve2Source = MixerSettings::CURVE2SOURCE_THROTTLE; @@ -1009,10 +1023,10 @@ void ConfigCcpmWidget::resizeEvent(QResizeEvent* event) { Q_UNUSED(event); // Make the custom table columns autostretch: - m_ccpm->ccpmAdvancedSettingsTable->resizeColumnsToContents(); + m_aircraft->ccpmAdvancedSettingsTable->resizeColumnsToContents(); for (int i=0;i<6;i++) { - m_ccpm->ccpmAdvancedSettingsTable->setColumnWidth(i,(m_ccpm->ccpmAdvancedSettingsTable->width()- - m_ccpm->ccpmAdvancedSettingsTable->verticalHeader()->width())/6); + m_aircraft->ccpmAdvancedSettingsTable->setColumnWidth(i,(m_aircraft->ccpmAdvancedSettingsTable->width()- + m_aircraft->ccpmAdvancedSettingsTable->verticalHeader()->width())/6); } ccpmSwashplateRedraw(); @@ -1020,10 +1034,10 @@ void ConfigCcpmWidget::resizeEvent(QResizeEvent* event) void ConfigCcpmWidget::showEvent(QShowEvent *event) { Q_UNUSED(event) - m_ccpm->ccpmAdvancedSettingsTable->resizeColumnsToContents(); + m_aircraft->ccpmAdvancedSettingsTable->resizeColumnsToContents(); for (int i=0;i<6;i++) { - m_ccpm->ccpmAdvancedSettingsTable->setColumnWidth(i,(m_ccpm->ccpmAdvancedSettingsTable->width()- - m_ccpm->ccpmAdvancedSettingsTable->verticalHeader()->width())/6); + m_aircraft->ccpmAdvancedSettingsTable->setColumnWidth(i,(m_aircraft->ccpmAdvancedSettingsTable->width()- + m_aircraft->ccpmAdvancedSettingsTable->verticalHeader()->width())/6); } ccpmSwashplateRedraw(); } @@ -1054,15 +1068,15 @@ void ConfigCcpmWidget::SwashLvlStartButtonPressed() //remove Flight control of ActuatorCommand enableSwashplateLevellingControl(true); - m_ccpm->SwashLvlStartButton->setEnabled(false); - m_ccpm->SwashLvlNextButton->setEnabled(true); - m_ccpm->SwashLvlCancelButton->setEnabled(true); - m_ccpm->SwashLvlFinishButton->setEnabled(false); + m_aircraft->SwashLvlStartButton->setEnabled(false); + m_aircraft->SwashLvlNextButton->setEnabled(true); + m_aircraft->SwashLvlCancelButton->setEnabled(true); + m_aircraft->SwashLvlFinishButton->setEnabled(false); //clear status check boxes - m_ccpm->SwashLvlStepList->item(0)->setCheckState(Qt::Unchecked); - m_ccpm->SwashLvlStepList->item(1)->setCheckState(Qt::Unchecked); - m_ccpm->SwashLvlStepList->item(2)->setCheckState(Qt::Unchecked); - m_ccpm->SwashLvlStepList->item(3)->setCheckState(Qt::Unchecked); + m_aircraft->SwashLvlStepList->item(0)->setCheckState(Qt::Unchecked); + m_aircraft->SwashLvlStepList->item(1)->setCheckState(Qt::Unchecked); + m_aircraft->SwashLvlStepList->item(2)->setCheckState(Qt::Unchecked); + m_aircraft->SwashLvlStepList->item(3)->setCheckState(Qt::Unchecked); //download the current settings to the OP hw @@ -1087,15 +1101,15 @@ void ConfigCcpmWidget::SwashLvlStartButtonPressed() MaxField = obj->getField(QString("ChannelMax")); //channel assignments - oldSwashLvlConfiguration.ServoChannels[0]=m_ccpm->ccpmServoWChannel->currentIndex(); - oldSwashLvlConfiguration.ServoChannels[1]=m_ccpm->ccpmServoXChannel->currentIndex(); - oldSwashLvlConfiguration.ServoChannels[2]=m_ccpm->ccpmServoYChannel->currentIndex(); - oldSwashLvlConfiguration.ServoChannels[3]=m_ccpm->ccpmServoZChannel->currentIndex(); + oldSwashLvlConfiguration.ServoChannels[0]=m_aircraft->ccpmServoWChannel->currentIndex(); + oldSwashLvlConfiguration.ServoChannels[1]=m_aircraft->ccpmServoXChannel->currentIndex(); + oldSwashLvlConfiguration.ServoChannels[2]=m_aircraft->ccpmServoYChannel->currentIndex(); + oldSwashLvlConfiguration.ServoChannels[3]=m_aircraft->ccpmServoZChannel->currentIndex(); //if servos are used - oldSwashLvlConfiguration.Used[0]=((m_ccpm->ccpmServoWChannel->currentIndex()>0)&&(m_ccpm->ccpmServoWChannel->isEnabled())); - oldSwashLvlConfiguration.Used[1]=((m_ccpm->ccpmServoXChannel->currentIndex()>0)&&(m_ccpm->ccpmServoXChannel->isEnabled())); - oldSwashLvlConfiguration.Used[2]=((m_ccpm->ccpmServoYChannel->currentIndex()>0)&&(m_ccpm->ccpmServoYChannel->isEnabled())); - oldSwashLvlConfiguration.Used[3]=((m_ccpm->ccpmServoZChannel->currentIndex()>0)&&(m_ccpm->ccpmServoZChannel->isEnabled())); + oldSwashLvlConfiguration.Used[0]=((m_aircraft->ccpmServoWChannel->currentIndex()>0)&&(m_aircraft->ccpmServoWChannel->isEnabled())); + oldSwashLvlConfiguration.Used[1]=((m_aircraft->ccpmServoXChannel->currentIndex()>0)&&(m_aircraft->ccpmServoXChannel->isEnabled())); + oldSwashLvlConfiguration.Used[2]=((m_aircraft->ccpmServoYChannel->currentIndex()>0)&&(m_aircraft->ccpmServoYChannel->isEnabled())); + oldSwashLvlConfiguration.Used[3]=((m_aircraft->ccpmServoZChannel->currentIndex()>0)&&(m_aircraft->ccpmServoZChannel->isEnabled())); //min,neutral,max values for the servos for (i=0;iSwashLvlStartButton->setEnabled(true); - m_ccpm->SwashLvlNextButton->setEnabled(false); - m_ccpm->SwashLvlCancelButton->setEnabled(false); - m_ccpm->SwashLvlFinishButton->setEnabled(false); + m_aircraft->SwashLvlStartButton->setEnabled(true); + m_aircraft->SwashLvlNextButton->setEnabled(false); + m_aircraft->SwashLvlCancelButton->setEnabled(false); + m_aircraft->SwashLvlFinishButton->setEnabled(false); break; default: // should never be reached break; } - - } + void ConfigCcpmWidget::SwashLvlNextButtonPressed() { //ShowDisclaimer(2); SwashLvlState++; - int i; - - - - switch (SwashLvlState) - { + switch (SwashLvlState) { case 0: break; case 1: //Neutral levelling - m_ccpm->SwashLvlStepList->setCurrentRow(0); + m_aircraft->SwashLvlStepList->setCurrentRow(0); //set spin boxes and swashplate servos to Neutral values setSwashplateLevel(50); //disable position slider - m_ccpm->SwashLvlPositionSlider->setEnabled(false); - m_ccpm->SwashLvlPositionSpinBox->setEnabled(false); + m_aircraft->SwashLvlPositionSlider->setEnabled(false); + m_aircraft->SwashLvlPositionSpinBox->setEnabled(false); //set position slider to 50% - m_ccpm->SwashLvlPositionSlider->setValue(50); - m_ccpm->SwashLvlPositionSpinBox->setValue(50); + m_aircraft->SwashLvlPositionSlider->setValue(50); + m_aircraft->SwashLvlPositionSpinBox->setValue(50); //connect spinbox signals to slots and ebnable them - for (i=0;isetEnabled(true); } //issue user instructions - m_ccpm->SwashLvlStepInstruction->setHtml("

Neutral levelling

Using adjustment of:

  • servo horns
  • link lengths and
  • Neutral timing spinboxes to the right

ensure that the swashplate is in the center of desired travel range and is level."); + m_aircraft->SwashLvlStepInstruction->setHtml( + "

Neutral levelling

Using adjustment of:

  • servo horns
  • link lengths and
  • Neutral timing spinboxes to the right

ensure that the swashplate is in the center of desired travel range and is level."); break; case 2: //Max levelling //check Neutral status as complete - m_ccpm->SwashLvlStepList->item(0)->setCheckState(Qt::Checked); - m_ccpm->SwashLvlStepList->setCurrentRow(1); + m_aircraft->SwashLvlStepList->item(0)->setCheckState(Qt::Checked); + m_aircraft->SwashLvlStepList->setCurrentRow(1); //set spin boxes and swashplate servos to Max values setSwashplateLevel(100); //set position slider to 100% - m_ccpm->SwashLvlPositionSlider->setValue(100); - m_ccpm->SwashLvlPositionSpinBox->setValue(100); + m_aircraft->SwashLvlPositionSlider->setValue(100); + m_aircraft->SwashLvlPositionSpinBox->setValue(100); //issue user instructions - m_ccpm->SwashLvlStepInstruction->setText("

Max levelling

Using adjustment of:

  • Max timing spinboxes to the right ONLY

ensure that the swashplate is at the top of desired travel range and is level."); + m_aircraft->SwashLvlStepInstruction->setText( + "

Max levelling

Using adjustment of:

  • Max timing spinboxes to the right ONLY

ensure that the swashplate is at the top of desired travel range and is level."); break; case 3: //Min levelling //check Max status as complete - m_ccpm->SwashLvlStepList->item(1)->setCheckState(Qt::Checked); - m_ccpm->SwashLvlStepList->setCurrentRow(2); + m_aircraft->SwashLvlStepList->item(1)->setCheckState(Qt::Checked); + m_aircraft->SwashLvlStepList->setCurrentRow(2); //set spin boxes and swashplate servos to Min values setSwashplateLevel(0); //set position slider to 0% - m_ccpm->SwashLvlPositionSlider->setValue(0); - m_ccpm->SwashLvlPositionSpinBox->setValue(0); + m_aircraft->SwashLvlPositionSlider->setValue(0); + m_aircraft->SwashLvlPositionSpinBox->setValue(0); //issue user instructions - m_ccpm->SwashLvlStepInstruction->setText("

Min levelling

Using adjustment of:

  • Min timing spinboxes to the right ONLY

ensure that the swashplate is at the bottom of desired travel range and is level."); - break; + m_aircraft->SwashLvlStepInstruction->setText( + "

Min levelling

Using adjustment of:

  • Min timing spinboxes to the right ONLY

ensure that the swashplate is at the bottom of desired travel range and is level."); + break; case 4: //levelling verification //check Min status as complete - m_ccpm->SwashLvlStepList->item(2)->setCheckState(Qt::Checked); - m_ccpm->SwashLvlStepList->setCurrentRow(3); + m_aircraft->SwashLvlStepList->item(2)->setCheckState(Qt::Checked); + m_aircraft->SwashLvlStepList->setCurrentRow(3); //enable position slider - m_ccpm->SwashLvlPositionSlider->setEnabled(true); - m_ccpm->SwashLvlPositionSpinBox->setEnabled(true); + m_aircraft->SwashLvlPositionSlider->setEnabled(true); + m_aircraft->SwashLvlPositionSpinBox->setEnabled(true); //make heli respond to slider movement - connect(m_ccpm->SwashLvlPositionSlider, SIGNAL(valueChanged(int)), this, SLOT(setSwashplateLevel(int))); + connect(m_aircraft->SwashLvlPositionSlider, SIGNAL(valueChanged(int)), this, SLOT(setSwashplateLevel(int))); //disable spin boxes - for (i=0;isetEnabled(false); } //issue user instructions - m_ccpm->SwashLvlStepInstruction->setText("

levelling verification

Adjust the slider to the right over it's full range and observe the swashplate motion. It should remain level over the entire range of travel."); - break; + m_aircraft->SwashLvlStepInstruction->setText( + "

levelling verification

Adjust the slider to the right over it's full range and observe the swashplate motion. It should remain level over the entire range of travel."); + break; case 5: //levelling complete //check verify status as complete - m_ccpm->SwashLvlStepList->item(3)->setCheckState(Qt::Checked); + m_aircraft->SwashLvlStepList->item(3)->setCheckState(Qt::Checked); //issue user instructions - m_ccpm->SwashLvlStepInstruction->setText("

levelling complete

Press the Finish button to save these settings to the SD card

Press the cancel button to return to the pre-levelling settings"); + m_aircraft->SwashLvlStepInstruction->setText( + "

levelling complete

Press the Finish button to save these settings to the SD card

Press the cancel button to return to the pre-levelling settings"); //disable position slider - m_ccpm->SwashLvlPositionSlider->setEnabled(false); - m_ccpm->SwashLvlPositionSpinBox->setEnabled(false); + m_aircraft->SwashLvlPositionSlider->setEnabled(false); + m_aircraft->SwashLvlPositionSpinBox->setEnabled(false); //disconnect levelling slots from signals - disconnect(m_ccpm->SwashLvlPositionSlider, SIGNAL(valueChanged(int)), this, SLOT(setSwashplateLevel(int))); - for (i=0;iSwashLvlPositionSlider, SIGNAL(valueChanged(int)), this, SLOT(setSwashplateLevel(int))); + for (int i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) { disconnect(SwashLvlSpinBoxes[i], SIGNAL(valueChanged(int)), this, SLOT(SwashLvlSpinBoxChanged(int))); } - m_ccpm->SwashLvlStartButton->setEnabled(false); - m_ccpm->SwashLvlNextButton->setEnabled(false); - m_ccpm->SwashLvlCancelButton->setEnabled(true); - m_ccpm->SwashLvlFinishButton->setEnabled(true); + m_aircraft->SwashLvlStartButton->setEnabled(false); + m_aircraft->SwashLvlNextButton->setEnabled(false); + m_aircraft->SwashLvlCancelButton->setEnabled(true); + m_aircraft->SwashLvlFinishButton->setEnabled(true); default: //restore collective/cyclic setting @@ -1231,24 +1241,24 @@ void ConfigCcpmWidget::SwashLvlNextButtonPressed() break; } } + void ConfigCcpmWidget::SwashLvlCancelButtonPressed() { - int i; - SwashLvlState=0; + SwashLvlState = 0; - UAVObjectField* MinField; - UAVObjectField* NeutralField; - UAVObjectField* MaxField; + UAVObjectField *MinField; + UAVObjectField *NeutralField; + UAVObjectField *MaxField; - m_ccpm->SwashLvlStartButton->setEnabled(true); - m_ccpm->SwashLvlNextButton->setEnabled(false); - m_ccpm->SwashLvlCancelButton->setEnabled(false); - m_ccpm->SwashLvlFinishButton->setEnabled(false); + m_aircraft->SwashLvlStartButton->setEnabled(true); + m_aircraft->SwashLvlNextButton->setEnabled(false); + m_aircraft->SwashLvlCancelButton->setEnabled(false); + m_aircraft->SwashLvlFinishButton->setEnabled(false); - m_ccpm->SwashLvlStepList->item(0)->setCheckState(Qt::Unchecked); - m_ccpm->SwashLvlStepList->item(1)->setCheckState(Qt::Unchecked); - m_ccpm->SwashLvlStepList->item(2)->setCheckState(Qt::Unchecked); - m_ccpm->SwashLvlStepList->item(3)->setCheckState(Qt::Unchecked); + m_aircraft->SwashLvlStepList->item(0)->setCheckState(Qt::Unchecked); + m_aircraft->SwashLvlStepList->item(1)->setCheckState(Qt::Unchecked); + m_aircraft->SwashLvlStepList->item(2)->setCheckState(Qt::Unchecked); + m_aircraft->SwashLvlStepList->item(3)->setCheckState(Qt::Unchecked); //restore old Actuator Settings ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); @@ -1260,110 +1270,110 @@ void ConfigCcpmWidget::SwashLvlCancelButtonPressed() NeutralField = obj->getField(QString("ChannelNeutral")); MaxField = obj->getField(QString("ChannelMax")); - //min,neutral,max values for the servos - for (i=0;isetValue(oldSwashLvlConfiguration.Min[i],oldSwashLvlConfiguration.ServoChannels[i]); - NeutralField->setValue(oldSwashLvlConfiguration.Neutral[i],oldSwashLvlConfiguration.ServoChannels[i]); - MaxField->setValue(oldSwashLvlConfiguration.Max[i],oldSwashLvlConfiguration.ServoChannels[i]); + // min,neutral,max values for the servos + for (int i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) { + MinField->setValue(oldSwashLvlConfiguration.Min[i], oldSwashLvlConfiguration.ServoChannels[i]); + NeutralField->setValue(oldSwashLvlConfiguration.Neutral[i], oldSwashLvlConfiguration.ServoChannels[i]); + MaxField->setValue(oldSwashLvlConfiguration.Max[i], oldSwashLvlConfiguration.ServoChannels[i]); } obj->updated(); - - //restore Flight control of ActuatorCommand + // restore Flight control of ActuatorCommand enableSwashplateLevellingControl(false); - m_ccpm->SwashLvlStepInstruction->setText("

Levelling Cancelled

Previous settings have been restored."); - + m_aircraft->SwashLvlStepInstruction->setText( + "

Levelling Cancelled

Previous settings have been restored."); } void ConfigCcpmWidget::SwashLvlFinishButtonPressed() { - int i; + UAVObjectField *MinField; + UAVObjectField *NeutralField; + UAVObjectField *MaxField; - UAVObjectField* MinField; - UAVObjectField* NeutralField; - UAVObjectField* MaxField; + m_aircraft->SwashLvlStartButton->setEnabled(true); + m_aircraft->SwashLvlNextButton->setEnabled(false); + m_aircraft->SwashLvlCancelButton->setEnabled(false); + m_aircraft->SwashLvlFinishButton->setEnabled(false); - m_ccpm->SwashLvlStartButton->setEnabled(true); - m_ccpm->SwashLvlNextButton->setEnabled(false); - m_ccpm->SwashLvlCancelButton->setEnabled(false); - m_ccpm->SwashLvlFinishButton->setEnabled(false); - - //save new Actuator Settings to memory and SD card + // save new Actuator Settings to memory and SD card ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectManager *objManager = pm->getObject(); UAVDataObject* obj = dynamic_cast(objManager->getObject(QString("ActuatorSettings"))); Q_ASSERT(obj); - //update settings to match our changes. + + // update settings to match our changes. MinField = obj->getField(QString("ChannelMin")); NeutralField = obj->getField(QString("ChannelNeutral")); MaxField = obj->getField(QString("ChannelMax")); - //min,neutral,max values for the servos - for (i=0;isetValue(newSwashLvlConfiguration.Min[i],newSwashLvlConfiguration.ServoChannels[i]); - NeutralField->setValue(newSwashLvlConfiguration.Neutral[i],newSwashLvlConfiguration.ServoChannels[i]); - MaxField->setValue(newSwashLvlConfiguration.Max[i],newSwashLvlConfiguration.ServoChannels[i]); + // min,neutral,max values for the servos + for (int i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) { + MinField->setValue(newSwashLvlConfiguration.Min[i], newSwashLvlConfiguration.ServoChannels[i]); + NeutralField->setValue(newSwashLvlConfiguration.Neutral[i], newSwashLvlConfiguration.ServoChannels[i]); + MaxField->setValue(newSwashLvlConfiguration.Max[i], newSwashLvlConfiguration.ServoChannels[i]); } obj->updated(); saveObjectToSD(obj); - //restore Flight control of ActuatorCommand + // restore Flight control of ActuatorCommand enableSwashplateLevellingControl(false); - m_ccpm->SwashLvlStepInstruction->setText("

Levelling Completed

New settings have been saved to the SD card"); + m_aircraft->SwashLvlStepInstruction->setText( + "

Levelling Completed

New settings have been saved to the SD card"); ShowDisclaimer(0); //ShowDisclaimer(2); - } int ConfigCcpmWidget::ShowDisclaimer(int messageID) { - QMessageBox msgBox; - msgBox.setText("

Warning!!!

"); - int ret; - switch (messageID) { - case 0: - // Basic disclaimer - msgBox.setInformativeText("

This code has many configurations.

Please double check all settings before attempting flight!"); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setDefaultButton(QMessageBox::Ok); - msgBox.setIcon(QMessageBox::Information); - ret = msgBox.exec(); - return 0; - break; - case 1: - // Not Tested disclaimer - msgBox.setInformativeText("

The CCPM mixer code needs more testing!

Use it at your own risk!

Do you wish to continue?"); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); - msgBox.setDefaultButton(QMessageBox::Cancel); - msgBox.setIcon(QMessageBox::Warning); - ret = msgBox.exec(); - switch (ret) - { - case QMessageBox::Cancel: return -1; - case QMessageBox::Yes: return 0; - } - break; - case 2: - // DO NOT use - msgBox.setInformativeText("

The CCPM swashplate levelling code is NOT complete!

DO NOT use it for flight!"); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setDefaultButton(QMessageBox::Ok); - msgBox.setIcon(QMessageBox::Critical); - ret = msgBox.exec(); + QMessageBox msgBox; + msgBox.setText("

Warning!!!

"); + int ret; + switch (messageID) { + case 0: + // Basic disclaimer + msgBox.setInformativeText( + "

This code has many configurations.

Please double check all settings before attempting flight!"); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + msgBox.setIcon(QMessageBox::Information); + ret = msgBox.exec(); + return 0; + break; + case 1: + // Not Tested disclaimer + msgBox.setInformativeText( + "

The CCPM mixer code needs more testing!

Use it at your own risk!

Do you wish to continue?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Cancel); + msgBox.setIcon(QMessageBox::Warning); + ret = msgBox.exec(); + switch (ret) { + case QMessageBox::Cancel: + return -1; + case QMessageBox::Yes: return 0; - break; - default: - // should never be reached - break; } + break; + case 2: + // DO NOT use + msgBox.setInformativeText( + "

The CCPM swashplate levelling code is NOT complete!

DO NOT use it for flight!"); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + msgBox.setIcon(QMessageBox::Critical); + ret = msgBox.exec(); + return 0; + break; + default: + // should never be reached + break; + } return -1; } @@ -1379,33 +1389,30 @@ void ConfigCcpmWidget::enableSwashplateLevellingControl(bool state) UAVDataObject* obj = dynamic_cast(objManager->getObject(QString("ActuatorCommand"))); UAVObject::Metadata mdata = obj->getMetadata(); - if (state) - { + if (state) { SwashLvlaccInitialData = mdata; UAVObject::SetFlightAccess(mdata, UAVObject::ACCESS_READONLY); UAVObject::SetFlightTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_ONCHANGE); UAVObject::SetGcsTelemetryAcked(mdata, false); UAVObject::SetGcsTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_ONCHANGE); mdata.gcsTelemetryUpdatePeriod = 100; - SwashLvlConfigurationInProgress=1; - m_ccpm->TabObject->setTabEnabled(0,0); - m_ccpm->TabObject->setTabEnabled(2,0); - m_ccpm->TabObject->setTabEnabled(3,0); - m_ccpm->ccpmType->setEnabled(0); - } - else - { - mdata = SwashLvlaccInitialData; // Restore metadata - SwashLvlConfigurationInProgress=0; + SwashLvlConfigurationInProgress = 1; + m_aircraft->TabObject->setTabEnabled(0, 0); + m_aircraft->TabObject->setTabEnabled(2, 0); + m_aircraft->TabObject->setTabEnabled(3, 0); + m_aircraft->ccpmType->setEnabled(0); + } else { + // Restore metadata + mdata = SwashLvlaccInitialData; + SwashLvlConfigurationInProgress = 0; - m_ccpm->TabObject->setTabEnabled(0,1); - m_ccpm->TabObject->setTabEnabled(2,1); - m_ccpm->TabObject->setTabEnabled(3,1); - m_ccpm->ccpmType->setEnabled(1); + m_aircraft->TabObject->setTabEnabled(0, 1); + m_aircraft->TabObject->setTabEnabled(2, 1); + m_aircraft->TabObject->setTabEnabled(3, 1); + m_aircraft->ccpmType->setEnabled(1); } obj->setMetadata(mdata); - } /** @@ -1414,26 +1421,34 @@ void ConfigCcpmWidget::enableSwashplateLevellingControl(bool state) */ void ConfigCcpmWidget::setSwashplateLevel(int percent) { - if (percent<0)return;// -1; - if (percent>100)return;// -1; - if (SwashLvlConfigurationInProgress!=1)return;// -1; - int i; - double value; - double level = ((double)percent /50.00) - 1.00; + if (percent < 0) { + return; // -1; + } + if (percent > 100) { + return; // -1; + } + if (SwashLvlConfigurationInProgress != 1) { + return; // -1; + } - SwashLvlServoInterlock=1; + double level = ((double) percent / 50.00) - 1.00; - ActuatorCommand * actuatorCommand = ActuatorCommand::GetInstance(getObjectManager()); + SwashLvlServoInterlock = 1; + + ActuatorCommand *actuatorCommand = ActuatorCommand::GetInstance(getObjectManager()); ActuatorCommand::DataFields actuatorCommandData = actuatorCommand->getData(); - for (i=0;i 0) - value = (newSwashLvlConfiguration.Max[i] - newSwashLvlConfiguration.Neutral[i])*level + newSwashLvlConfiguration.Neutral[i]; - else if (level < 0) - value = (newSwashLvlConfiguration.Neutral[i] - newSwashLvlConfiguration.Min[i])*level + newSwashLvlConfiguration.Neutral[i]; - + } else if (level > 0) { + value = (newSwashLvlConfiguration.Max[i] - newSwashLvlConfiguration.Neutral[i]) * level + + newSwashLvlConfiguration.Neutral[i]; + } else if (level < 0) { + value = (newSwashLvlConfiguration.Neutral[i] - newSwashLvlConfiguration.Min[i]) * level + + newSwashLvlConfiguration.Neutral[i]; + } actuatorCommandData.Channel[newSwashLvlConfiguration.ServoChannels[i]] = value; SwashLvlSpinBoxes[i]->setValue(value); } @@ -1441,38 +1456,42 @@ void ConfigCcpmWidget::setSwashplateLevel(int percent) actuatorCommand->setData(actuatorCommandData); actuatorCommand->updated(); - SwashLvlServoInterlock=0; - -return; + SwashLvlServoInterlock = 0; } void ConfigCcpmWidget::SwashLvlSpinBoxChanged(int value) { Q_UNUSED(value); - int i; - if (SwashLvlServoInterlock==1)return; - ActuatorCommand * actuatorCommand = ActuatorCommand::GetInstance(getObjectManager()); + if (SwashLvlServoInterlock == 1) { + return; + } + + ActuatorCommand *actuatorCommand = ActuatorCommand::GetInstance(getObjectManager()); ActuatorCommand::DataFields actuatorCommandData = actuatorCommand->getData(); - for (i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) { + for (int i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) { value = SwashLvlSpinBoxes[i]->value(); - switch (SwashLvlState) - { - case 1: //Neutral levelling - newSwashLvlConfiguration.Neutral[i]=value; + switch (SwashLvlState) { + case 1: + // Neutral levelling + newSwashLvlConfiguration.Neutral[i] = value; break; - case 2: //Max levelling + case 2: + // Max levelling newSwashLvlConfiguration.Max[i] = value; break; - case 3: //Min levelling - newSwashLvlConfiguration.Min[i]= value; + case 3: + // Min levelling + newSwashLvlConfiguration.Min[i] = value; break; - case 4: //levelling verification + case 4: + // levelling verification break; - case 5: //levelling complete + case 5: + // levelling complete break; default: break; @@ -1481,7 +1500,6 @@ void ConfigCcpmWidget::SwashLvlSpinBoxChanged(int value) actuatorCommandData.Channel[newSwashLvlConfiguration.ServoChannels[i]] = value; } - actuatorCommand->setData(actuatorCommandData); actuatorCommand->updated(); @@ -1497,63 +1515,45 @@ bool ConfigCcpmWidget::throwConfigError(QString airframeType) bool error = false; - if((m_ccpm->ccpmServoWChannel->currentIndex()==0) && (m_ccpm->ccpmServoWChannel->isEnabled())) - { - m_ccpm->ccpmServoWLabel->setText("" + m_ccpm->ccpmServoWLabel->text() + ""); + if ((m_aircraft->ccpmServoWChannel->currentIndex() == 0) && (m_aircraft->ccpmServoWChannel->isEnabled())) { + m_aircraft->ccpmServoWLabel->setText("" + m_aircraft->ccpmServoWLabel->text() + ""); error = true; - } - else - { - m_ccpm->ccpmServoWLabel->setText(QTextEdit(m_ccpm->ccpmServoWLabel->text()).toPlainText()); + } else { + m_aircraft->ccpmServoWLabel->setText(QTextEdit(m_aircraft->ccpmServoWLabel->text()).toPlainText()); } - if((m_ccpm->ccpmServoXChannel->currentIndex()==0) && (m_ccpm->ccpmServoXChannel->isEnabled())) - { - m_ccpm->ccpmServoXLabel->setText("" + m_ccpm->ccpmServoXLabel->text() + ""); + if ((m_aircraft->ccpmServoXChannel->currentIndex() == 0) && (m_aircraft->ccpmServoXChannel->isEnabled())) { + m_aircraft->ccpmServoXLabel->setText("" + m_aircraft->ccpmServoXLabel->text() + ""); error = true; - } - else - { - m_ccpm->ccpmServoXLabel->setText(QTextEdit(m_ccpm->ccpmServoXLabel->text()).toPlainText()); + } else { + m_aircraft->ccpmServoXLabel->setText(QTextEdit(m_aircraft->ccpmServoXLabel->text()).toPlainText()); } - if((m_ccpm->ccpmServoYChannel->currentIndex()==0) && (m_ccpm->ccpmServoYChannel->isEnabled())) - { - m_ccpm->ccpmServoYLabel->setText("" + m_ccpm->ccpmServoYLabel->text() + ""); + if ((m_aircraft->ccpmServoYChannel->currentIndex() == 0) && (m_aircraft->ccpmServoYChannel->isEnabled())) { + m_aircraft->ccpmServoYLabel->setText("" + m_aircraft->ccpmServoYLabel->text() + ""); error = true; - } - else - { - m_ccpm->ccpmServoYLabel->setText(QTextEdit(m_ccpm->ccpmServoYLabel->text()).toPlainText()); + } else { + m_aircraft->ccpmServoYLabel->setText(QTextEdit(m_aircraft->ccpmServoYLabel->text()).toPlainText()); } - if((m_ccpm->ccpmServoZChannel->currentIndex()==0) && (m_ccpm->ccpmServoZChannel->isEnabled())) - { - m_ccpm->ccpmServoZLabel->setText("" + m_ccpm->ccpmServoZLabel->text()+ ""); + if ((m_aircraft->ccpmServoZChannel->currentIndex() == 0) && (m_aircraft->ccpmServoZChannel->isEnabled())) { + m_aircraft->ccpmServoZLabel->setText("" + m_aircraft->ccpmServoZLabel->text() + ""); error = true; - } - else - { - m_ccpm->ccpmServoZLabel->setText(QTextEdit(m_ccpm->ccpmServoZLabel->text()).toPlainText()); + } else { + m_aircraft->ccpmServoZLabel->setText(QTextEdit(m_aircraft->ccpmServoZLabel->text()).toPlainText()); } - if((m_ccpm->ccpmEngineChannel->currentIndex()==0) && (m_ccpm->ccpmEngineChannel->isEnabled())) - { - m_ccpm->ccpmEngineLabel->setText("" + m_ccpm->ccpmEngineLabel->text() + ""); - } - else - { - m_ccpm->ccpmEngineLabel->setText(QTextEdit(m_ccpm->ccpmEngineLabel->text()).toPlainText()); + if ((m_aircraft->ccpmEngineChannel->currentIndex() == 0) && (m_aircraft->ccpmEngineChannel->isEnabled())) { + m_aircraft->ccpmEngineLabel->setText("" + m_aircraft->ccpmEngineLabel->text() + ""); + } else { + m_aircraft->ccpmEngineLabel->setText(QTextEdit(m_aircraft->ccpmEngineLabel->text()).toPlainText()); } - if((m_ccpm->ccpmTailChannel->currentIndex()==0) && (m_ccpm->ccpmTailChannel->isEnabled())) - { - m_ccpm->ccpmTailLabel->setText("" + m_ccpm->ccpmTailLabel->text() + ""); + if ((m_aircraft->ccpmTailChannel->currentIndex() == 0) && (m_aircraft->ccpmTailChannel->isEnabled())) { + m_aircraft->ccpmTailLabel->setText("" + m_aircraft->ccpmTailLabel->text() + ""); error = true; - } - else - { - m_ccpm->ccpmTailLabel->setText(QTextEdit(m_ccpm->ccpmTailLabel->text()).toPlainText()); + } else { + m_aircraft->ccpmTailLabel->setText(QTextEdit(m_aircraft->ccpmTailLabel->text()).toPlainText()); } diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.h b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.h index 2d52eed8f..a0e4fa094 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.h +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configccpmwidget.h @@ -27,12 +27,13 @@ #ifndef CONFIGccpmWIDGET_H #define CONFIGccpmWIDGET_H -#include "ui_ccpm.h" -#include "../uavobjectwidgetutils/configtaskwidget.h" #include "cfg_vehicletypes/vehicleconfig.h" +#include "ui_airframe_ccpm.h" +#include "../uavobjectwidgetutils/configtaskwidget.h" #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" #include "uavobject.h" + #include #include #include @@ -51,83 +52,85 @@ typedef struct { int Min[CCPM_MAX_SWASH_SERVOS]; } SwashplateServoSettingsStruct; - class ConfigCcpmWidget: public VehicleConfig { Q_OBJECT public: + static QStringList getChannelDescriptions(); + ConfigCcpmWidget(QWidget *parent = 0); ~ConfigCcpmWidget(); - friend class ConfigVehicleTypeWidget; + virtual void refreshWidgetsValues(QString frameType); + virtual QString updateConfigObjectsFromWidgets(); -private: - Ui_ccpmWidget *m_ccpm; - QGraphicsSvgItem *SwashplateImg; - QGraphicsSvgItem *CurveImg; - QGraphicsSvgItem *Servos[CCPM_MAX_SWASH_SERVOS]; - QGraphicsTextItem *ServosText[CCPM_MAX_SWASH_SERVOS]; - QGraphicsLineItem *ServoLines[CCPM_MAX_SWASH_SERVOS]; - QGraphicsEllipseItem *ServosTextCircles[CCPM_MAX_SWASH_SERVOS]; - QSpinBox *SwashLvlSpinBoxes[CCPM_MAX_SWASH_SERVOS]; - - QString TypeText; - - bool SwashLvlConfigurationInProgress; - UAVObject::Metadata SwashLvlaccInitialData; - int SwashLvlState; - int SwashLvlServoInterlock; - - SwashplateServoSettingsStruct oldSwashLvlConfiguration; - SwashplateServoSettingsStruct newSwashLvlConfiguration; - - int MixerChannelData[6]; - int ShowDisclaimer(int messageID); - virtual void enableControls(bool enable) { Q_UNUSED(enable)}; // Not used by this widget - - bool updatingFromHardware; - bool updatingToHardware; - - virtual void ResetActuators(GUIConfigDataUnion* configData); - static QStringList getChannelDescriptions(); - - QString updateConfigObjects(); - private slots: - virtual void setupUI(QString airframeType); - virtual void refreshWidgetsValues(QString frameType); - virtual QString updateConfigObjectsFromWidgets(); - virtual bool throwConfigError(QString airframeType); - - void ccpmSwashplateUpdate(); - void ccpmSwashplateRedraw(); - void UpdateMixer(); - void UpdateType(); - - void SwashLvlStartButtonPressed(); - void SwashLvlNextButtonPressed(); - void SwashLvlCancelButtonPressed(); - void SwashLvlFinishButtonPressed(); - - //void UpdateCCPMOptionsFromUI(); - //void UpdateCCPMUIFromOptions(); - - void SetUIComponentVisibilities(); - - void enableSwashplateLevellingControl(bool state); - void setSwashplateLevel(int percent); - void SwashLvlSpinBoxChanged(int value); - virtual void refreshValues() {}; // Not used - - public slots: - void getMixer(); - void setMixer(); - void saveccpmUpdate(); +public slots: + void getMixer(); + void setMixer(); + void saveccpmUpdate(); protected: void showEvent(QShowEvent *event); void resizeEvent(QResizeEvent *event); +private: + Ui_CcpmConfigWidget *m_aircraft; + + QGraphicsSvgItem *SwashplateImg; + QGraphicsSvgItem *CurveImg; + QGraphicsSvgItem *Servos[CCPM_MAX_SWASH_SERVOS]; + QGraphicsTextItem *ServosText[CCPM_MAX_SWASH_SERVOS]; + QGraphicsLineItem *ServoLines[CCPM_MAX_SWASH_SERVOS]; + QGraphicsEllipseItem *ServosTextCircles[CCPM_MAX_SWASH_SERVOS]; + QSpinBox *SwashLvlSpinBoxes[CCPM_MAX_SWASH_SERVOS]; + + QString TypeText; + + bool SwashLvlConfigurationInProgress; + UAVObject::Metadata SwashLvlaccInitialData; + int SwashLvlState; + int SwashLvlServoInterlock; + + SwashplateServoSettingsStruct oldSwashLvlConfiguration; + SwashplateServoSettingsStruct newSwashLvlConfiguration; + + int MixerChannelData[6]; + + virtual void registerWidgets(ConfigTaskWidget &parent); + virtual void resetActuators(GUIConfigDataUnion *configData); + + int ShowDisclaimer(int messageID); + virtual void enableControls(bool enable) { Q_UNUSED(enable) }; // Not used by this widget + + bool updatingFromHardware; + bool updatingToHardware; + + QString updateConfigObjects(); + +private slots: + virtual void setupUI(QString airframeType); + virtual bool throwConfigError(QString airframeType); + + void ccpmSwashplateUpdate(); + void ccpmSwashplateRedraw(); + void UpdateMixer(); + void UpdateType(); + + void SwashLvlStartButtonPressed(); + void SwashLvlNextButtonPressed(); + void SwashLvlCancelButtonPressed(); + void SwashLvlFinishButtonPressed(); + + //void UpdateCCPMOptionsFromUI(); + //void UpdateCCPMUIFromOptions(); + + void SetUIComponentVisibilities(); + + void enableSwashplateLevellingControl(bool state); + void setSwashplateLevel(int percent); + void SwashLvlSpinBoxChanged(int value); + virtual void refreshValues() {}; // Not used }; #endif // CONFIGccpmWIDGET_H diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.cpp b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.cpp new file mode 100644 index 000000000..684435b0a --- /dev/null +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.cpp @@ -0,0 +1,296 @@ +/** + ****************************************************************************** + * + * @file configmultirotorwidget.cpp + * @author E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup ConfigPlugin Config Plugin + * @{ + * @brief ccpm configuration panel + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "configcustomwidget.h" +#include "mixersettings.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QStringList ConfigCustomWidget::getChannelDescriptions() +{ + QStringList channelDesc; + for (int i = 0; i < (int) VehicleConfig::CHANNEL_NUMELEM; i++) { + channelDesc.append(QString("-")); + } + return channelDesc; +} + +ConfigCustomWidget::ConfigCustomWidget(QWidget *parent) : + VehicleConfig(parent), m_aircraft(new Ui_CustomConfigWidget()) +{ + m_aircraft->setupUi(this); + + // Put combo boxes in line one of the custom mixer table: + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); + Q_ASSERT(mixer); + + UAVObjectField* field = mixer->getField(QString("Mixer1Type")); + QStringList list = field->getOptions(); + for (int i = 0; i < (int) VehicleConfig::CHANNEL_NUMELEM; i++) { + QComboBox* qb = new QComboBox(m_aircraft->customMixerTable); + qb->addItems(list); + m_aircraft->customMixerTable->setCellWidget(0, i, qb); + } + + SpinBoxDelegate *sbd = new SpinBoxDelegate(); + for (int i = 1; i < (int) VehicleConfig::CHANNEL_NUMELEM; i++) { + m_aircraft->customMixerTable->setItemDelegateForRow(i, sbd); + } + +} + +ConfigCustomWidget::~ConfigCustomWidget() +{ + delete m_aircraft; +} + +void ConfigCustomWidget::setupUI(QString frameType) +{ + Q_ASSERT(m_aircraft); +} + +void ConfigCustomWidget::registerWidgets(ConfigTaskWidget &parent) { + parent.addWidget(m_aircraft->customMixerTable); + parent.addWidget(m_aircraft->customThrottle1Curve->getCurveWidget()); + parent.addWidget(m_aircraft->customThrottle2Curve->getCurveWidget()); +} + +void ConfigCustomWidget::resetActuators(GUIConfigDataUnion *configData) +{ +} + +/** + Helper function to refresh the UI widget values + */ +void ConfigCustomWidget::refreshWidgetsValues(QString frameType) +{ + Q_ASSERT(m_aircraft); + + setupUI(frameType); + + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); + Q_ASSERT(mixer); + + QList curveValues; + getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, &curveValues); + + // is at least one of the curve values != 0? + if (isValidThrottleCurve(&curveValues)) { + // yes, use the curve we just read from mixersettings + m_aircraft->customThrottle1Curve->initCurve(&curveValues); + } + else { + // no, init a straight curve + m_aircraft->customThrottle1Curve->initLinearCurve(curveValues.count(), 1.0); + } + + if (MixerSettings *mxr = qobject_cast(mixer)) { + MixerSettings::DataFields mixerSettingsData = mxr->getData(); + if (mixerSettingsData.Curve2Source == MixerSettings::CURVE2SOURCE_THROTTLE) + m_aircraft->customThrottle2Curve->setMixerType(MixerCurve::MIXERCURVE_THROTTLE); + else { + m_aircraft->customThrottle2Curve->setMixerType(MixerCurve::MIXERCURVE_PITCH); + } + } + + // Setup all Throttle2 curves for all types of airframes + getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, &curveValues); + + if (isValidThrottleCurve(&curveValues)) { + m_aircraft->customThrottle2Curve->initCurve(&curveValues); + } + else { + m_aircraft->customThrottle2Curve->initLinearCurve(curveValues.count(), 1.0, m_aircraft->customThrottle2Curve->getMin()); + } + + // Update the mixer table: + for (int channel = 0; channel < m_aircraft->customMixerTable->columnCount(); channel++) { + UAVObjectField* field = mixer->getField(mixerTypes.at(channel)); + if (field) { + QComboBox* q = (QComboBox*) m_aircraft->customMixerTable->cellWidget(0, channel); + if (q) { + QString s = field->getValue().toString(); + setComboCurrentIndex(q, q->findText(s)); + } + + m_aircraft->customMixerTable->item(1, channel)->setText( + QString::number(getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1))); + m_aircraft->customMixerTable->item(2, channel)->setText( + QString::number(getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2))); + m_aircraft->customMixerTable->item(3, channel)->setText( + QString::number(getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL))); + m_aircraft->customMixerTable->item(4, channel)->setText( + QString::number(getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH))); + m_aircraft->customMixerTable->item(5, channel)->setText( + QString::number(getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW))); + } + } +} + +/** + Helper function to + */ +QString ConfigCustomWidget::updateConfigObjectsFromWidgets() +{ + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); + Q_ASSERT(mixer); + + setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->customThrottle1Curve->getCurve()); + setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, m_aircraft->customThrottle2Curve->getCurve()); + + // Update the table: + for (int channel = 0; channel < (int) VehicleConfig::CHANNEL_NUMELEM; channel++) { + QComboBox* q = (QComboBox*) m_aircraft->customMixerTable->cellWidget(0, channel); + if (q->currentText() == "Disabled") { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_DISABLED); + } else if (q->currentText() == "Motor") { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_MOTOR); + } else if (q->currentText() == "Servo") { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); + } else if (q->currentText() == "CameraRoll") { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_CAMERAROLL); + } else if (q->currentText() == "CameraPitch") { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_CAMERAPITCH); + } else if (q->currentText() == "CameraYaw") { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_CAMERAYAW); + } else if (q->currentText() == "Accessory0") { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY0); + } else if (q->currentText() == "Accessory1") { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY1); + } else if (q->currentText() == "Accessory2") { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY2); + } else if (q->currentText() == "Accessory3") { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY3); + } else if (q->currentText() == "Accessory4") { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY4); + } else if (q->currentText() == "Accessory5") { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_ACCESSORY5); + } + setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, + m_aircraft->customMixerTable->item(1, channel)->text().toDouble()); + setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, + m_aircraft->customMixerTable->item(2, channel)->text().toDouble()); + setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, + m_aircraft->customMixerTable->item(3, channel)->text().toDouble()); + setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, + m_aircraft->customMixerTable->item(4, channel)->text().toDouble()); + setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, + m_aircraft->customMixerTable->item(5, channel)->text().toDouble()); + } + + return "Custom"; +} + +/** + This function displays text and color formatting in order to help the user understand what channels have not yet been configured. + */ +bool ConfigCustomWidget::throwConfigError(int numMotors) +{ + return false; +} + +/** + WHAT DOES THIS DO??? + */ +void ConfigCustomWidget::showEvent(QShowEvent *event) +{ + Q_UNUSED(event); + // Make the custom table columns autostretch: + m_aircraft->customMixerTable->resizeColumnsToContents(); + int channelCount = (int) VehicleConfig::CHANNEL_NUMELEM; + for (int i = 0; i < channelCount; i++) { + m_aircraft->customMixerTable->setColumnWidth(i, + (m_aircraft->customMixerTable->width() - m_aircraft->customMixerTable->verticalHeader()->width()) + / channelCount); + } +} + +/** + Resize the GUI contents when the user changes the window size + */ +void ConfigCustomWidget::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + // Make the custom table columns autostretch: + m_aircraft->customMixerTable->resizeColumnsToContents(); + int channelCount = (int) VehicleConfig::CHANNEL_NUMELEM; + for (int i = 0; i < channelCount; i++) { + m_aircraft->customMixerTable->setColumnWidth(i, + (m_aircraft->customMixerTable->width() - m_aircraft->customMixerTable->verticalHeader()->width()) + / channelCount); + } +} + +/** + Helper delegate for the custom mixer editor table. + Taken straight from Qt examples, thanks! +*/ +SpinBoxDelegate::SpinBoxDelegate(QObject *parent) : + QItemDelegate(parent) +{ +} + +QWidget *SpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QSpinBox *editor = new QSpinBox(parent); + editor->setMinimum(-127); + editor->setMaximum(127); + + return editor; +} + +void SpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + int value = index.model()->data(index, Qt::EditRole).toInt(); + + QSpinBox *spinBox = static_cast(editor); + spinBox->setValue(value); +} + +void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + QSpinBox *spinBox = static_cast(editor); + spinBox->interpretText(); + int value = spinBox->value(); + + model->setData(index, value, Qt::EditRole); +} + +void SpinBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + editor->setGeometry(option.rect); +} diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.h b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.h new file mode 100644 index 000000000..1bf7bbf75 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configcustomwidget.h @@ -0,0 +1,88 @@ +/** + ****************************************************************************** + * + * @file configairframetwidget.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup ConfigPlugin Config Plugin + * @{ + * @brief Airframe configuration panel + *****************************************************************************/ +/* + * 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 CONFIGCUSTOMWIDGET_H +#define CONFIGCUSTOMWIDGET_H + +#include "cfg_vehicletypes/vehicleconfig.h" +#include "ui_airframe_custom.h" +#include "../uavobjectwidgetutils/configtaskwidget.h" +#include "extensionsystem/pluginmanager.h" +#include "uavobjectmanager.h" +#include "uavobject.h" +#include "uavtalk/telemetrymanager.h" + +#include +#include +#include + +class Ui_Widget; + +class ConfigCustomWidget: public VehicleConfig +{ + Q_OBJECT + +public: + static QStringList getChannelDescriptions(); + + ConfigCustomWidget(QWidget *parent = 0); + ~ConfigCustomWidget(); + + virtual void refreshWidgetsValues(QString frameType); + virtual QString updateConfigObjectsFromWidgets(); + +protected: + void showEvent(QShowEvent *event); + void resizeEvent(QResizeEvent *event); + +private: + Ui_CustomConfigWidget *m_aircraft; + + virtual void registerWidgets(ConfigTaskWidget &parent); + virtual void resetActuators(GUIConfigDataUnion *configData); + +private slots: + virtual void setupUI(QString airframeType); + virtual bool throwConfigError(int numMotors); + +}; + +class SpinBoxDelegate : public QItemDelegate +{ + Q_OBJECT + +public: + SpinBoxDelegate(QObject *parent = 0); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + void setEditorData(QWidget *editor, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; +}; + +#endif // CONFIGCUSTOMWIDGET_H diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp index ac6d91165..a2b7bf79f 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.cpp @@ -25,8 +25,10 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configfixedwingwidget.h" -#include "configvehicletypewidget.h" #include "mixersettings.h" +#include "systemsettings.h" +#include "actuatorsettings.h" +#include "actuatorcommand.h" #include #include @@ -38,29 +40,65 @@ #include #include -#include "mixersettings.h" -#include "systemsettings.h" -#include "actuatorsettings.h" -#include "actuatorcommand.h" - - -/** - Constructor - */ -ConfigFixedWingWidget::ConfigFixedWingWidget(Ui_AircraftWidget *aircraft, QWidget *parent) : VehicleConfig(parent) +QStringList ConfigFixedWingWidget::getChannelDescriptions() { - m_aircraft = aircraft; + // init a channel_numelem list of channel desc defaults + QStringList channelDesc; + for (int i = 0; i < (int) ConfigFixedWingWidget::CHANNEL_NUMELEM; i++) { + channelDesc.append(QString("-")); + } + + // get the gui config data + GUIConfigDataUnion configData = getConfigData(); + + if (configData.fixedwing.FixedWingPitch1 > 0) { + channelDesc[configData.fixedwing.FixedWingPitch1 - 1] = QString("FixedWingPitch1"); + } + if (configData.fixedwing.FixedWingPitch2 > 0) { + channelDesc[configData.fixedwing.FixedWingPitch2 - 1] = QString("FixedWingPitch2"); + } + if (configData.fixedwing.FixedWingRoll1 > 0) { + channelDesc[configData.fixedwing.FixedWingRoll1 - 1] = QString("FixedWingRoll1"); + } + if (configData.fixedwing.FixedWingRoll2 > 0) { + channelDesc[configData.fixedwing.FixedWingRoll2 - 1] = QString("FixedWingRoll2"); + } + if (configData.fixedwing.FixedWingYaw1 > 0) { + channelDesc[configData.fixedwing.FixedWingYaw1 - 1] = QString("FixedWingYaw1"); + } + if (configData.fixedwing.FixedWingYaw2 > 0) { + channelDesc[configData.fixedwing.FixedWingYaw2 - 1] = QString("FixedWingYaw2"); + } + if (configData.fixedwing.FixedWingThrottle > 0) { + channelDesc[configData.fixedwing.FixedWingThrottle - 1] = QString("FixedWingThrottle"); + } + return channelDesc; +} + +ConfigFixedWingWidget::ConfigFixedWingWidget(QWidget *parent) : + VehicleConfig(parent), m_aircraft(new Ui_FixedWingConfigWidget()) +{ + m_aircraft->setupUi(this); + + populateChannelComboBoxes(); + + QStringList fixedWingTypes; + fixedWingTypes << "Elevator aileron rudder" << "Elevon" << "Vtail"; + m_aircraft->fixedWingType->addItems(fixedWingTypes); + + // Set default model to "Elevator aileron rudder" + m_aircraft->fixedWingType->setCurrentIndex(m_aircraft->fixedWingType->findText("Elevator aileron rudder")); + + //setupUI(m_aircraft->fixedWingType->currentText()); + + connect(m_aircraft->fixedWingType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupUI(QString))); } -/** - Destructor - */ ConfigFixedWingWidget::~ConfigFixedWingWidget() { - // Do nothing + delete m_aircraft; } - /** Virtual function to setup the UI */ @@ -69,8 +107,6 @@ void ConfigFixedWingWidget::setupUI(QString frameType) Q_ASSERT(m_aircraft); if (frameType == "FixedWing" || frameType == "Elevator aileron rudder") { - // Setup the UI - setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Fixed Wing")); setComboCurrentIndex(m_aircraft->fixedWingType, m_aircraft->fixedWingType->findText("Elevator aileron rudder")); m_aircraft->fwRudder1ChannelBox->setEnabled(true); m_aircraft->fwRudder1Label->setEnabled(true); @@ -92,7 +128,6 @@ void ConfigFixedWingWidget::setupUI(QString frameType) m_aircraft->elevonMixBox->setHidden(true); } else if (frameType == "FixedWingElevon" || frameType == "Elevon") { - setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Fixed Wing")); setComboCurrentIndex(m_aircraft->fixedWingType, m_aircraft->fixedWingType->findText("Elevon")); m_aircraft->fwAileron1Label->setText("Elevon 1"); m_aircraft->fwAileron2Label->setText("Elevon 2"); @@ -111,7 +146,6 @@ void ConfigFixedWingWidget::setupUI(QString frameType) m_aircraft->elevonLabel2->setText("Pitch"); } else if (frameType == "FixedWingVtail" || frameType == "Vtail") { - setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Fixed Wing")); setComboCurrentIndex(m_aircraft->fixedWingType, m_aircraft->fixedWingType->findText("Vtail")); m_aircraft->fwRudder1ChannelBox->setEnabled(false); m_aircraft->fwRudder1Label->setEnabled(false); @@ -131,7 +165,22 @@ void ConfigFixedWingWidget::setupUI(QString frameType) } } -void ConfigFixedWingWidget::ResetActuators(GUIConfigDataUnion* configData) +void ConfigFixedWingWidget::registerWidgets(ConfigTaskWidget &parent) { + parent.addWidget(m_aircraft->fixedWingThrottle->getCurveWidget()); + parent.addWidget(m_aircraft->fixedWingType); + + parent.addWidget(m_aircraft->fwEngineChannelBox); + parent.addWidget(m_aircraft->fwAileron1ChannelBox); + parent.addWidget(m_aircraft->fwAileron2ChannelBox); + parent.addWidget(m_aircraft->fwElevator1ChannelBox); + parent.addWidget(m_aircraft->fwElevator2ChannelBox); + parent.addWidget(m_aircraft->fwRudder1ChannelBox); + parent.addWidget(m_aircraft->fwRudder2ChannelBox); + parent.addWidget(m_aircraft->elevonSlider1); + parent.addWidget(m_aircraft->elevonSlider2); +} + +void ConfigFixedWingWidget::resetActuators(GUIConfigDataUnion *configData) { configData->fixedwing.FixedWingPitch1 = 0; configData->fixedwing.FixedWingPitch2 = 0; @@ -142,36 +191,65 @@ void ConfigFixedWingWidget::ResetActuators(GUIConfigDataUnion* configData) configData->fixedwing.FixedWingThrottle = 0; } -QStringList ConfigFixedWingWidget::getChannelDescriptions() +/** + Virtual function to refresh the UI widget values + */ +void ConfigFixedWingWidget::refreshWidgetsValues(QString frameType) { - int i; - QStringList channelDesc; + Q_ASSERT(m_aircraft); - // init a channel_numelem list of channel desc defaults - for (i=0; i < (int)(ConfigFixedWingWidget::CHANNEL_NUMELEM); i++) - { - channelDesc.append(QString("-")); + setupUI(frameType); + + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); + Q_ASSERT(mixer); + + QList curveValues; + getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, &curveValues); + + // is at least one of the curve values != 0? + if (isValidThrottleCurve(&curveValues)) { + // yes, use the curve we just read from mixersettings + m_aircraft->fixedWingThrottle->initCurve(&curveValues); + } + else { + // no, init a straight curve + m_aircraft->fixedWingThrottle->initLinearCurve(curveValues.count(), 1.0); } - // get the gui config data - GUIConfigDataUnion configData = GetConfigData(); + GUIConfigDataUnion config = getConfigData(); + fixedGUISettingsStruct fixed = config.fixedwing; - if (configData.fixedwing.FixedWingPitch1 > 0) - channelDesc[configData.fixedwing.FixedWingPitch1-1] = QString("FixedWingPitch1"); - if (configData.fixedwing.FixedWingPitch2 > 0) - channelDesc[configData.fixedwing.FixedWingPitch2-1] = QString("FixedWingPitch2"); - if (configData.fixedwing.FixedWingRoll1 > 0) - channelDesc[configData.fixedwing.FixedWingRoll1-1] = QString("FixedWingRoll1"); - if (configData.fixedwing.FixedWingRoll2 > 0) - channelDesc[configData.fixedwing.FixedWingRoll2-1] = QString("FixedWingRoll2"); - if (configData.fixedwing.FixedWingYaw1 > 0) - channelDesc[configData.fixedwing.FixedWingYaw1-1] = QString("FixedWingYaw1"); - if (configData.fixedwing.FixedWingYaw2 > 0) - channelDesc[configData.fixedwing.FixedWingYaw2-1] = QString("FixedWingYaw2"); - if (configData.fixedwing.FixedWingThrottle > 0) - channelDesc[configData.fixedwing.FixedWingThrottle-1] = QString("FixedWingThrottle"); + // Then retrieve how channels are setup + setComboCurrentIndex(m_aircraft->fwEngineChannelBox, fixed.FixedWingThrottle); + setComboCurrentIndex(m_aircraft->fwAileron1ChannelBox, fixed.FixedWingRoll1); + setComboCurrentIndex(m_aircraft->fwAileron2ChannelBox, fixed.FixedWingRoll2); + setComboCurrentIndex(m_aircraft->fwElevator1ChannelBox, fixed.FixedWingPitch1); + setComboCurrentIndex(m_aircraft->fwElevator2ChannelBox, fixed.FixedWingPitch2); + setComboCurrentIndex(m_aircraft->fwRudder1ChannelBox, fixed.FixedWingYaw1); + setComboCurrentIndex(m_aircraft->fwRudder2ChannelBox, fixed.FixedWingYaw2); - return channelDesc; + if (frameType == "FixedWingElevon") { + // If the airframe is elevon, restore the slider setting + // Find the channel number for Elevon1 (FixedWingRoll1) + int channel = m_aircraft->fwAileron1ChannelBox->currentIndex() - 1; + if (channel > -1) { + // If for some reason the actuators were incoherent, we might fail here, hence the check. + m_aircraft->elevonSlider1->setValue( + getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL) * 100); + m_aircraft->elevonSlider2->setValue( + getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH) * 100); + } + } + else if (frameType == "FixedWingVtail") { + int channel = m_aircraft->fwElevator1ChannelBox->currentIndex() - 1; + if (channel > -1) { + // If for some reason the actuators were incoherent, we might fail here, hence the check. + m_aircraft->elevonSlider1->setValue( + getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW) * 100); + m_aircraft->elevonSlider2->setValue( + getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH) * 100); + } + } } /** @@ -180,18 +258,18 @@ QStringList ConfigFixedWingWidget::getChannelDescriptions() QString ConfigFixedWingWidget::updateConfigObjectsFromWidgets() { QString airframeType = "FixedWing"; - + // Save the curve (common to all Fixed wing frames) UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); // Remove Feed Forward, it is pointless on a plane: setMixerValue(mixer, "FeedForward", 0.0); - + // Set the throttle curve setThrottleCurve(mixer,VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->fixedWingThrottle->getCurve()); - //All airframe types must start with "FixedWing" + // All airframe types must start with "FixedWing" if (m_aircraft->fixedWingType->currentText() == "Elevator aileron rudder" ) { airframeType = "FixedWing"; setupFrameFixedWing( airframeType ); @@ -206,50 +284,6 @@ QString ConfigFixedWingWidget::updateConfigObjectsFromWidgets() return airframeType; } - -/** - Virtual function to refresh the UI widget values - */ -void ConfigFixedWingWidget::refreshWidgetsValues(QString frameType) -{ - Q_ASSERT(m_aircraft); - - GUIConfigDataUnion config = GetConfigData(); - fixedGUISettingsStruct fixed = config.fixedwing; - - // Then retrieve how channels are setup - setComboCurrentIndex(m_aircraft->fwEngineChannelBox, fixed.FixedWingThrottle); - setComboCurrentIndex(m_aircraft->fwAileron1ChannelBox, fixed.FixedWingRoll1); - setComboCurrentIndex(m_aircraft->fwAileron2ChannelBox, fixed.FixedWingRoll2); - setComboCurrentIndex(m_aircraft->fwElevator1ChannelBox, fixed.FixedWingPitch1); - setComboCurrentIndex(m_aircraft->fwElevator2ChannelBox, fixed.FixedWingPitch2); - setComboCurrentIndex(m_aircraft->fwRudder1ChannelBox, fixed.FixedWingYaw1); - setComboCurrentIndex(m_aircraft->fwRudder2ChannelBox, fixed.FixedWingYaw2); - - UAVDataObject* mixer= dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(mixer); - - int channel; - if (frameType == "FixedWingElevon") { - // If the airframe is elevon, restore the slider setting - // Find the channel number for Elevon1 (FixedWingRoll1) - channel = m_aircraft->fwAileron1ChannelBox->currentIndex()-1; - if (channel > -1) { // If for some reason the actuators were incoherent, we might fail here, hence the check. - m_aircraft->elevonSlider1->setValue(getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_ROLL)*100); - m_aircraft->elevonSlider2->setValue(getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_PITCH)*100); - } - } - if (frameType == "FixedWingVtail") { - channel = m_aircraft->fwElevator1ChannelBox->currentIndex()-1; - if (channel > -1) { // If for some reason the actuators were incoherent, we might fail here, hence the check. - m_aircraft->elevonSlider1->setValue(getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_YAW)*100); - m_aircraft->elevonSlider2->setValue(getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_PITCH)*100); - } - } -} - - - /** Setup Elevator/Aileron/Rudder airframe. @@ -260,15 +294,14 @@ void ConfigFixedWingWidget::refreshWidgetsValues(QString frameType) bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType) { // Check coherence: - //Show any config errors in GUI + // Show any config errors in GUI if (throwConfigError(airframeType)) { - return false; - } + return false; + } // Now setup the channels: - - GUIConfigDataUnion config = GetConfigData(); - ResetActuators(&config); + GUIConfigDataUnion config = getConfigData(); + resetActuators(&config); config.fixedwing.FixedWingPitch1 = m_aircraft->fwElevator1ChannelBox->currentIndex(); config.fixedwing.FixedWingPitch2 = m_aircraft->fwElevator2ChannelBox->currentIndex(); @@ -277,8 +310,8 @@ bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType) config.fixedwing.FixedWingYaw1 = m_aircraft->fwRudder1ChannelBox->currentIndex(); config.fixedwing.FixedWingThrottle = m_aircraft->fwEngineChannelBox->currentIndex(); - SetConfigData(config); - + setConfigData(config); + UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); resetMotorAndServoMixers(mixer); @@ -289,58 +322,56 @@ bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType) // 1. Assign the servo/motor/none for each channel - //motor - int channel = m_aircraft->fwEngineChannelBox->currentIndex()-1; - setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_MOTOR); - setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); + // motor + int channel = m_aircraft->fwEngineChannelBox->currentIndex() - 1; + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_MOTOR); + setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); - //rudder - channel = m_aircraft->fwRudder1ChannelBox->currentIndex()-1; - setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); + // rudder + channel = m_aircraft->fwRudder1ChannelBox->currentIndex() - 1; + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127); - //ailerons - channel = m_aircraft->fwAileron1ChannelBox->currentIndex()-1; + // ailerons + channel = m_aircraft->fwAileron1ChannelBox->currentIndex() - 1; if (channel > -1) { - setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, 127); - channel = m_aircraft->fwAileron2ChannelBox->currentIndex()-1; - setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); + channel = m_aircraft->fwAileron2ChannelBox->currentIndex() - 1; + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, 127); } - //elevators - channel = m_aircraft->fwElevator1ChannelBox->currentIndex()-1; + // elevators + channel = m_aircraft->fwElevator1ChannelBox->currentIndex() - 1; if (channel > -1) { - setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, 127); - channel = m_aircraft->fwElevator2ChannelBox->currentIndex()-1; - setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); + channel = m_aircraft->fwElevator2ChannelBox->currentIndex() - 1; + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, 127); } m_aircraft->fwStatusLabel->setText("Mixer generated"); - + return true; } - - /** Setup Elevon */ bool ConfigFixedWingWidget::setupFrameElevon(QString airframeType) { // Check coherence: - //Show any config errors in GUI + // Show any config errors in GUI if (throwConfigError(airframeType)) { return false; } - - GUIConfigDataUnion config = GetConfigData(); - ResetActuators(&config); + + GUIConfigDataUnion config = getConfigData(); + resetActuators(&config); config.fixedwing.FixedWingRoll1 = m_aircraft->fwAileron1ChannelBox->currentIndex(); config.fixedwing.FixedWingRoll2 = m_aircraft->fwAileron2ChannelBox->currentIndex(); @@ -348,8 +379,8 @@ bool ConfigFixedWingWidget::setupFrameElevon(QString airframeType) config.fixedwing.FixedWingYaw2 = m_aircraft->fwRudder2ChannelBox->currentIndex(); config.fixedwing.FixedWingThrottle = m_aircraft->fwEngineChannelBox->currentIndex(); - SetConfigData(config); - + setConfigData(config); + UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); resetMotorAndServoMixers(mixer); @@ -363,34 +394,34 @@ bool ConfigFixedWingWidget::setupFrameElevon(QString airframeType) double value; - //motor - int channel = m_aircraft->fwEngineChannelBox->currentIndex()-1; - setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_MOTOR); - setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); + // motor + int channel = m_aircraft->fwEngineChannelBox->currentIndex() - 1; + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_MOTOR); + setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); - //rudders - channel = m_aircraft->fwRudder1ChannelBox->currentIndex()-1; - setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); + // rudders + channel = m_aircraft->fwRudder1ChannelBox->currentIndex() - 1; + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127); - channel = m_aircraft->fwRudder2ChannelBox->currentIndex()-1; - setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); + channel = m_aircraft->fwRudder2ChannelBox->currentIndex() - 1; + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127); - //ailerons - channel = m_aircraft->fwAileron1ChannelBox->currentIndex()-1; + // ailerons + channel = m_aircraft->fwAileron1ChannelBox->currentIndex() - 1; if (channel > -1) { - setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); - value = (double)(m_aircraft->elevonSlider2->value()*1.27); + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); + value = (double) (m_aircraft->elevonSlider2->value() * 1.27); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, value); - value = (double)(m_aircraft->elevonSlider1->value()*1.27); + value = (double) (m_aircraft->elevonSlider1->value() * 1.27); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, value); - channel = m_aircraft->fwAileron2ChannelBox->currentIndex()-1; - setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); - value = (double)(m_aircraft->elevonSlider2->value()*1.27); + channel = m_aircraft->fwAileron2ChannelBox->currentIndex() - 1; + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); + value = (double) (m_aircraft->elevonSlider2->value() * 1.27); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, value); - value = (double)(m_aircraft->elevonSlider1->value()*1.27); + value = (double) (m_aircraft->elevonSlider1->value() * 1.27); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, -value); } @@ -398,21 +429,19 @@ bool ConfigFixedWingWidget::setupFrameElevon(QString airframeType) return true; } - - /** Setup VTail */ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType) { // Check coherence: - //Show any config errors in GUI + // Show any config errors in GUI if (throwConfigError(airframeType)) { return false; } - GUIConfigDataUnion config = GetConfigData(); - ResetActuators(&config); + GUIConfigDataUnion config = getConfigData(); + resetActuators(&config); config.fixedwing.FixedWingPitch1 = m_aircraft->fwElevator1ChannelBox->currentIndex(); config.fixedwing.FixedWingPitch2 = m_aircraft->fwElevator2ChannelBox->currentIndex(); @@ -420,7 +449,7 @@ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType) config.fixedwing.FixedWingRoll2 = m_aircraft->fwAileron2ChannelBox->currentIndex(); config.fixedwing.FixedWingThrottle = m_aircraft->fwEngineChannelBox->currentIndex(); - SetConfigData(config); + setConfigData(config); UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); @@ -433,14 +462,12 @@ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType) // 1. Assign the servo/motor/none for each channel - double value; - - //motor + // motor int channel = m_aircraft->fwEngineChannelBox->currentIndex()-1; setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_MOTOR); setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); - //rudders + // rudders channel = m_aircraft->fwRudder1ChannelBox->currentIndex()-1; setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127); @@ -449,7 +476,7 @@ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType) setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127); - //ailerons + // ailerons channel = m_aircraft->fwAileron1ChannelBox->currentIndex()-1; if (channel > -1) { setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); @@ -460,11 +487,11 @@ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType) setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, -127); } - //vtail + // vtail channel = m_aircraft->fwElevator1ChannelBox->currentIndex()-1; if (channel > -1) { setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); - value = (double)(m_aircraft->elevonSlider2->value()*1.27); + double value = (double)(m_aircraft->elevonSlider2->value()*1.27); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, value); value = (double)(m_aircraft->elevonSlider1->value()*1.27); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, value); @@ -486,96 +513,88 @@ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType) */ bool ConfigFixedWingWidget::throwConfigError(QString airframeType) { - //Initialize configuration error flag - bool error=false; - - //Create a red block. All combo boxes are the same size, so any one should do as a model - int size = m_aircraft->fwEngineChannelBox->style()->pixelMetric(QStyle::PM_SmallIconSize); - QPixmap pixmap(size,size); - pixmap.fill(QColor("red")); - - if (airframeType == "FixedWing" ) { - if (m_aircraft->fwEngineChannelBox->currentText() == "None"){ - m_aircraft->fwEngineChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else{ - m_aircraft->fwEngineChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - - if (m_aircraft->fwElevator1ChannelBox->currentText() == "None"){ - m_aircraft->fwElevator1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else{ - m_aircraft->fwElevator1ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - - if ((m_aircraft->fwAileron1ChannelBox->currentText() == "None") && (m_aircraft->fwRudder1ChannelBox->currentText() == "None")) { - pixmap.fill(QColor("green")); - m_aircraft->fwAileron1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - m_aircraft->fwRudder1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else{ - m_aircraft->fwAileron1ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - m_aircraft->fwRudder1ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - } else if (airframeType == "FixedWingElevon"){ - if (m_aircraft->fwEngineChannelBox->currentText() == "None"){ - m_aircraft->fwEngineChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else{ - m_aircraft->fwEngineChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - - if(m_aircraft->fwAileron1ChannelBox->currentText() == "None"){ - m_aircraft->fwAileron1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else{ - m_aircraft->fwAileron1ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - - if (m_aircraft->fwAileron2ChannelBox->currentText() == "None"){ - m_aircraft->fwAileron2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else{ - m_aircraft->fwAileron2ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - - } else if ( airframeType == "FixedWingVtail"){ - if (m_aircraft->fwEngineChannelBox->currentText() == "None"){ - m_aircraft->fwEngineChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else{ - m_aircraft->fwEngineChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - - if(m_aircraft->fwElevator1ChannelBox->currentText() == "None"){ - m_aircraft->fwElevator1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else{ - m_aircraft->fwElevator1ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - - if(m_aircraft->fwElevator2ChannelBox->currentText() == "None"){ - m_aircraft->fwElevator2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else{ - m_aircraft->fwElevator2ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - - } - - if (error){ - m_aircraft->fwStatusLabel->setText(QString("ERROR: Assign all necessary channels")); - } + // Initialize configuration error flag + bool error = false; + + // Create a red block. All combo boxes are the same size, so any one should do as a model + int size = m_aircraft->fwEngineChannelBox->style()->pixelMetric(QStyle::PM_SmallIconSize); + QPixmap pixmap(size, size); + pixmap.fill(QColor("red")); + + if (airframeType == "FixedWing") { + if (m_aircraft->fwEngineChannelBox->currentText() == "None") { + m_aircraft->fwEngineChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + m_aircraft->fwEngineChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + + if (m_aircraft->fwElevator1ChannelBox->currentText() == "None") { + m_aircraft->fwElevator1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + m_aircraft->fwElevator1ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + + if ((m_aircraft->fwAileron1ChannelBox->currentText() == "None") + && (m_aircraft->fwRudder1ChannelBox->currentText() == "None")) { + pixmap.fill(QColor("green")); + m_aircraft->fwAileron1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + m_aircraft->fwRudder1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + m_aircraft->fwAileron1ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + m_aircraft->fwRudder1ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + } else if (airframeType == "FixedWingElevon") { + if (m_aircraft->fwEngineChannelBox->currentText() == "None") { + m_aircraft->fwEngineChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + m_aircraft->fwEngineChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + + if (m_aircraft->fwAileron1ChannelBox->currentText() == "None") { + m_aircraft->fwAileron1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + m_aircraft->fwAileron1ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + + if (m_aircraft->fwAileron2ChannelBox->currentText() == "None") { + m_aircraft->fwAileron2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + m_aircraft->fwAileron2ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + + } else if (airframeType == "FixedWingVtail") { + if (m_aircraft->fwEngineChannelBox->currentText() == "None") { + m_aircraft->fwEngineChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + m_aircraft->fwEngineChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + + if (m_aircraft->fwElevator1ChannelBox->currentText() == "None") { + m_aircraft->fwElevator1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + m_aircraft->fwElevator1ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + + if (m_aircraft->fwElevator2ChannelBox->currentText() == "None") { + m_aircraft->fwElevator2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + m_aircraft->fwElevator2ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + + } + + if (error) { + m_aircraft->fwStatusLabel->setText(QString("ERROR: Assign all necessary channels")); + } return error; } diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.h b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.h index 7897829b3..c738920d9 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.h +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configfixedwingwidget.h @@ -27,12 +27,14 @@ #ifndef CONFIGFIXEDWINGWIDGET_H #define CONFIGFIXEDWINGWIDGET_H -#include "ui_airframe.h" +#include "cfg_vehicletypes/vehicleconfig.h" +#include "ui_airframe_fixedwing.h" #include "../uavobjectwidgetutils/configtaskwidget.h" #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" #include "uavobject.h" #include "uavtalk/telemetrymanager.h" + #include #include #include @@ -44,31 +46,28 @@ class ConfigFixedWingWidget: public VehicleConfig Q_OBJECT public: - ConfigFixedWingWidget(Ui_AircraftWidget *aircraft = 0, QWidget *parent = 0); + static QStringList getChannelDescriptions(); + + ConfigFixedWingWidget(QWidget *parent = 0); ~ConfigFixedWingWidget(); - friend class ConfigVehicleTypeWidget; + virtual void refreshWidgetsValues(QString frameType); + virtual QString updateConfigObjectsFromWidgets(); private: - Ui_AircraftWidget *m_aircraft; + Ui_FixedWingConfigWidget *m_aircraft; + + virtual void registerWidgets(ConfigTaskWidget &parent); + virtual void resetActuators(GUIConfigDataUnion *configData); bool setupFrameFixedWing(QString airframeType); bool setupFrameElevon(QString airframeType); bool setupFrameVtail(QString airframeType); - virtual void ResetActuators(GUIConfigDataUnion* configData); - static QStringList getChannelDescriptions(); - private slots: virtual void setupUI(QString airframeType); - virtual void refreshWidgetsValues(QString frameType); - virtual QString updateConfigObjectsFromWidgets(); virtual bool throwConfigError(QString airframeType); - -protected: - }; - #endif // CONFIGFIXEDWINGWIDGET_H diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.cpp b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.cpp index a23b758df..771a2afb5 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.cpp @@ -25,8 +25,10 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configgroundvehiclewidget.h" -#include "configvehicletypewidget.h" #include "mixersettings.h" +#include "systemsettings.h" +#include "actuatorsettings.h" +#include "actuatorcommand.h" #include #include @@ -35,29 +37,58 @@ #include #include #include -#include #include -#include "mixersettings.h" -#include "systemsettings.h" -#include "actuatorsettings.h" -#include "actuatorcommand.h" +#include - -/** - Constructor - */ -ConfigGroundVehicleWidget::ConfigGroundVehicleWidget(Ui_AircraftWidget *aircraft, QWidget *parent) : VehicleConfig(parent) +QStringList ConfigGroundVehicleWidget::getChannelDescriptions() { - m_aircraft = aircraft; + // init a channel_numelem list of channel desc defaults + QStringList channelDesc; + for (int i = 0; i < (int) ConfigGroundVehicleWidget::CHANNEL_NUMELEM; i++) { + channelDesc.append(QString("-")); + } + + // get the gui config data + GUIConfigDataUnion configData = getConfigData(); + + if (configData.ground.GroundVehicleSteering1 > 0) { + channelDesc[configData.ground.GroundVehicleSteering1 - 1] = QString("GroundSteering1"); + } + if (configData.ground.GroundVehicleSteering2 > 0) { + channelDesc[configData.ground.GroundVehicleSteering2 - 1] = QString("GroundSteering2"); + } + if (configData.ground.GroundVehicleThrottle1 > 0) { + channelDesc[configData.ground.GroundVehicleThrottle1 - 1] = QString("GroundThrottle1"); + } + if (configData.ground.GroundVehicleThrottle2 > 0) { + channelDesc[configData.ground.GroundVehicleThrottle2 - 1] = QString("GroundThrottle2"); + } + return channelDesc; +} + +ConfigGroundVehicleWidget::ConfigGroundVehicleWidget(QWidget *parent) : + VehicleConfig(parent), m_aircraft(new Ui_GroundConfigWidget()) +{ + m_aircraft->setupUi(this); + + populateChannelComboBoxes(); + + QStringList groundVehicleTypes; + groundVehicleTypes << "Turnable (car)" << "Differential (tank)" << "Motorcycle"; + m_aircraft->groundVehicleType->addItems(groundVehicleTypes); + + // Set default model to "Turnable (car)" + m_aircraft->groundVehicleType->setCurrentIndex(m_aircraft->groundVehicleType->findText("Turnable (car)")); + + //setupUI(m_aircraft->groundVehicleType->currentText()); + + connect(m_aircraft->groundVehicleType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupUI(QString))); } -/** - Destructor - */ ConfigGroundVehicleWidget::~ConfigGroundVehicleWidget() { - // Do nothing + delete m_aircraft; } /** @@ -65,96 +96,103 @@ ConfigGroundVehicleWidget::~ConfigGroundVehicleWidget() */ void ConfigGroundVehicleWidget::setupUI(QString frameType) { - m_aircraft->differentialSteeringMixBox->setHidden(true); - //STILL NEEDS WORK - // Setup the UI - setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Ground")); - - m_aircraft->gvEngineChannelBox->setEnabled(false); - m_aircraft->gvEngineLabel->setEnabled(false); + m_aircraft->differentialSteeringMixBox->setHidden(true); + //STILL NEEDS WORK - - m_aircraft->gvAileron1ChannelBox->setEnabled(false); - m_aircraft->gvAileron1Label->setEnabled(false); - - m_aircraft->gvAileron2ChannelBox->setEnabled(false); - m_aircraft->gvAileron2Label->setEnabled(false); - - if (frameType == "GroundVehicleDifferential" || frameType == "Differential (tank)"){ //Tank - setComboCurrentIndex(m_aircraft->groundVehicleType, m_aircraft->groundVehicleType->findText("Differential (tank)")); - m_aircraft->gvMotor1ChannelBox->setEnabled(true); - m_aircraft->gvMotor1Label->setEnabled(true); - - m_aircraft->gvMotor2ChannelBox->setEnabled(true); - m_aircraft->gvMotor2Label->setEnabled(true); + // Setup the UI - m_aircraft->gvMotor1Label->setText("Left motor"); - m_aircraft->gvMotor2Label->setText("Right motor"); + m_aircraft->gvEngineChannelBox->setEnabled(false); + m_aircraft->gvEngineLabel->setEnabled(false); - m_aircraft->gvSteering1ChannelBox->setEnabled(false); - m_aircraft->gvSteering1Label->setEnabled(false); - - m_aircraft->gvSteering2ChannelBox->setEnabled(false); - m_aircraft->gvSteering2Label->setEnabled(false); + m_aircraft->gvAileron1ChannelBox->setEnabled(false); + m_aircraft->gvAileron1Label->setEnabled(false); - m_aircraft->gvSteering2Label->setText("Rear steering"); + m_aircraft->gvAileron2ChannelBox->setEnabled(false); + m_aircraft->gvAileron2Label->setEnabled(false); - m_aircraft->differentialSteeringMixBox->setHidden(false); + if (frameType == "GroundVehicleDifferential" || frameType == "Differential (tank)") { + // Tank + setComboCurrentIndex(m_aircraft->groundVehicleType, + m_aircraft->groundVehicleType->findText("Differential (tank)")); + m_aircraft->gvMotor1ChannelBox->setEnabled(true); + m_aircraft->gvMotor1Label->setEnabled(true); - m_aircraft->gvThrottleCurve1GroupBox->setTitle("Left throttle curve"); - m_aircraft->gvThrottleCurve2GroupBox->setTitle("Right throttle curve"); + m_aircraft->gvMotor2ChannelBox->setEnabled(true); + m_aircraft->gvMotor2Label->setEnabled(true); - } - else if (frameType == "GroundVehicleMotorcycle" || frameType == "Motorcycle"){ //Motorcycle + m_aircraft->gvMotor1Label->setText("Left motor"); + m_aircraft->gvMotor2Label->setText("Right motor"); + + m_aircraft->gvSteering1ChannelBox->setEnabled(false); + m_aircraft->gvSteering1Label->setEnabled(false); + + m_aircraft->gvSteering2ChannelBox->setEnabled(false); + m_aircraft->gvSteering2Label->setEnabled(false); + + m_aircraft->gvSteering2Label->setText("Rear steering"); + + m_aircraft->differentialSteeringMixBox->setHidden(false); + + m_aircraft->gvThrottleCurve1GroupBox->setTitle("Left throttle curve"); + m_aircraft->gvThrottleCurve2GroupBox->setTitle("Right throttle curve"); + + } else if (frameType == "GroundVehicleMotorcycle" || frameType == "Motorcycle") { + // Motorcycle setComboCurrentIndex(m_aircraft->groundVehicleType, m_aircraft->groundVehicleType->findText("Motorcycle")); - m_aircraft->gvMotor1ChannelBox->setEnabled(false); - m_aircraft->gvMotor1Label->setEnabled(false); + m_aircraft->gvMotor1ChannelBox->setEnabled(false); + m_aircraft->gvMotor1Label->setEnabled(false); - m_aircraft->gvMotor2ChannelBox->setEnabled(true); - m_aircraft->gvMotor2Label->setEnabled(true); + m_aircraft->gvMotor2ChannelBox->setEnabled(true); + m_aircraft->gvMotor2Label->setEnabled(true); - m_aircraft->gvMotor1Label->setText("Front motor"); - m_aircraft->gvMotor2Label->setText("Rear motor"); + m_aircraft->gvMotor1Label->setText("Front motor"); + m_aircraft->gvMotor2Label->setText("Rear motor"); - m_aircraft->gvSteering1ChannelBox->setEnabled(true); - m_aircraft->gvSteering1Label->setEnabled(true); - - m_aircraft->gvSteering2ChannelBox->setEnabled(true); - m_aircraft->gvSteering2Label->setEnabled(true); + m_aircraft->gvSteering1ChannelBox->setEnabled(true); + m_aircraft->gvSteering1Label->setEnabled(true); - m_aircraft->gvSteering2Label->setText("Balancing"); + m_aircraft->gvSteering2ChannelBox->setEnabled(true); + m_aircraft->gvSteering2Label->setEnabled(true); - m_aircraft->differentialSteeringMixBox->setHidden(true); - - m_aircraft->gvThrottleCurve1GroupBox->setTitle("Front throttle curve"); - m_aircraft->gvThrottleCurve2GroupBox->setTitle("Rear throttle curve"); - } - else {//Car + m_aircraft->gvSteering2Label->setText("Balancing"); + + m_aircraft->differentialSteeringMixBox->setHidden(true); + + m_aircraft->gvThrottleCurve1GroupBox->setTitle("Front throttle curve"); + m_aircraft->gvThrottleCurve2GroupBox->setTitle("Rear throttle curve"); + } else { + // Car setComboCurrentIndex(m_aircraft->groundVehicleType, m_aircraft->groundVehicleType->findText("Turnable (car)")); - - m_aircraft->gvMotor1ChannelBox->setEnabled(true); - m_aircraft->gvMotor1Label->setEnabled(true); - m_aircraft->gvMotor2ChannelBox->setEnabled(true); - m_aircraft->gvMotor2Label->setEnabled(true); - - m_aircraft->gvMotor1Label->setText("Front motor"); - m_aircraft->gvMotor2Label->setText("Rear motor"); - - m_aircraft->gvSteering1ChannelBox->setEnabled(true); - m_aircraft->gvSteering1Label->setEnabled(true); - - m_aircraft->gvSteering2ChannelBox->setEnabled(true); - m_aircraft->gvSteering2Label->setEnabled(true); - - m_aircraft->differentialSteeringMixBox->setHidden(true); - - m_aircraft->gvThrottleCurve1GroupBox->setTitle("Front throttle curve"); - m_aircraft->gvThrottleCurve2GroupBox->setTitle("Rear throttle curve"); - } + m_aircraft->gvMotor1ChannelBox->setEnabled(true); + m_aircraft->gvMotor1Label->setEnabled(true); + + m_aircraft->gvMotor2ChannelBox->setEnabled(true); + m_aircraft->gvMotor2Label->setEnabled(true); + + m_aircraft->gvMotor1Label->setText("Front motor"); + m_aircraft->gvMotor2Label->setText("Rear motor"); + + m_aircraft->gvSteering1ChannelBox->setEnabled(true); + m_aircraft->gvSteering1Label->setEnabled(true); + + m_aircraft->gvSteering2ChannelBox->setEnabled(true); + m_aircraft->gvSteering2Label->setEnabled(true); + + m_aircraft->differentialSteeringMixBox->setHidden(true); + + m_aircraft->gvThrottleCurve1GroupBox->setTitle("Front throttle curve"); + m_aircraft->gvThrottleCurve2GroupBox->setTitle("Rear throttle curve"); + } } -void ConfigGroundVehicleWidget::ResetActuators(GUIConfigDataUnion* configData) +void ConfigGroundVehicleWidget::registerWidgets(ConfigTaskWidget &parent) { + parent.addWidget(m_aircraft->groundVehicleThrottle1->getCurveWidget()); + parent.addWidget(m_aircraft->groundVehicleThrottle2->getCurveWidget()); + parent.addWidget(m_aircraft->groundVehicleType); +} + +void ConfigGroundVehicleWidget::resetActuators(GUIConfigDataUnion *configData) { configData->ground.GroundVehicleSteering1 = 0; configData->ground.GroundVehicleSteering2 = 0; @@ -162,213 +200,202 @@ void ConfigGroundVehicleWidget::ResetActuators(GUIConfigDataUnion* configData) configData->ground.GroundVehicleThrottle2 = 0; } -QStringList ConfigGroundVehicleWidget::getChannelDescriptions() +/** + Virtual function to refresh the UI widget values + */ +void ConfigGroundVehicleWidget::refreshWidgetsValues(QString frameType) { - int i; - QStringList channelDesc; + setupUI(frameType); - // init a channel_numelem list of channel desc defaults - for (i=0; i < (int)(ConfigGroundVehicleWidget::CHANNEL_NUMELEM); i++) - { - channelDesc.append(QString("-")); + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); + Q_ASSERT(mixer); + + QList curveValues; + getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, &curveValues); + + // is at least one of the curve values != 0? + if (isValidThrottleCurve(&curveValues)) { + // yes, use the curve we just read from mixersettings + m_aircraft->groundVehicleThrottle1->initCurve(&curveValues); + } else { + // no, init a straight curve + m_aircraft->groundVehicleThrottle1->initLinearCurve(curveValues.count(), 1.0); } - // get the gui config data - GUIConfigDataUnion configData = GetConfigData(); + // Setup all Throttle2 curves for all types of airframes + getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, &curveValues); - if (configData.ground.GroundVehicleSteering1 > 0) - channelDesc[configData.ground.GroundVehicleSteering1-1] = QString("GroundSteering1"); - if (configData.ground.GroundVehicleSteering2 > 0) - channelDesc[configData.ground.GroundVehicleSteering2-1] = QString("GroundSteering2"); - if (configData.ground.GroundVehicleThrottle1 > 0) - channelDesc[configData.ground.GroundVehicleThrottle1-1] = QString("GroundThrottle1"); - if (configData.ground.GroundVehicleThrottle2 > 0) - channelDesc[configData.ground.GroundVehicleThrottle2-1] = QString("GroundThrottle2"); + if (isValidThrottleCurve(&curveValues)) { + m_aircraft->groundVehicleThrottle2->initCurve(&curveValues); + } else { + m_aircraft->groundVehicleThrottle2->initLinearCurve(curveValues.count(), 1.0); + } + GUIConfigDataUnion config = getConfigData(); - return channelDesc; + // THIS SECTION STILL NEEDS WORK. FOR THE MOMENT, USE THE FIXED-WING ONBOARD SETTING IN ORDER TO MINIMIZE CHANCES OF BOLLOXING REAL CODE + // Retrieve channel setup values + setComboCurrentIndex(m_aircraft->gvMotor1ChannelBox, config.ground.GroundVehicleThrottle1); + setComboCurrentIndex(m_aircraft->gvMotor2ChannelBox, config.ground.GroundVehicleThrottle2); + setComboCurrentIndex(m_aircraft->gvSteering1ChannelBox, config.ground.GroundVehicleSteering1); + setComboCurrentIndex(m_aircraft->gvSteering2ChannelBox, config.ground.GroundVehicleSteering2); + + if (frameType == "GroundVehicleDifferential") { + //CURRENTLY BROKEN UNTIL WE DECIDE HOW DIFFERENTIAL SHOULD BEHAVE + // If the vehicle type is "differential", restore the slider setting + + // Find the channel number for Motor1 + //obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); + //Q_ASSERT(obj); + int channel = m_aircraft->gvMotor1ChannelBox->currentIndex() - 1; + if (channel > -1) { + // If for some reason the actuators were incoherent, we might fail here, hence the check. + m_aircraft->differentialSteeringSlider1->setValue( + getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL) * 100); + m_aircraft->differentialSteeringSlider2->setValue( + getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH) * 100); + } + } else if (frameType == "GroundVehicleMotorcycle") { + // CURRENTLY BROKEN UNTIL WE DECIDE HOW MOTORCYCLE SHOULD BEHAVE +// obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); +// Q_ASSERT(obj); +// int chMixerNumber = m_aircraft->gvMotor1ChannelBox->currentIndex()-1; +// if (chMixerNumber >=0) { +// field = obj->getField(mixerVectors.at(chMixerNumber)); +// int ti = field->getElementNames().indexOf("Yaw"); +// m_aircraft->differentialSteeringSlider1->setValue(field->getDouble(ti)*100); +// +// ti = field->getElementNames().indexOf("Pitch"); +// m_aircraft->differentialSteeringSlider2->setValue(field->getDouble(ti)*100); +// } + } } - - /** Virtual function to update the UI widget objects */ QString ConfigGroundVehicleWidget::updateConfigObjectsFromWidgets() { - QString airframeType = "GroundVehicleCar"; - - // Save the curve (common to all ground vehicle frames) + QString airframeType = "GroundVehicleCar"; + + // Save the curve (common to all ground vehicle frames) UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - - // Remove Feed Forward, it is pointless on a ground vehicle: + + // Remove Feed Forward, it is pointless on a ground vehicle: setMixerValue(mixer, "FeedForward", 0.0); // set the throttle curves - setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->groundVehicleThrottle1->getCurve() ); - setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, m_aircraft->groundVehicleThrottle2->getCurve() ); + setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->groundVehicleThrottle1->getCurve()); + setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, m_aircraft->groundVehicleThrottle2->getCurve()); - //All airframe types must start with "GroundVehicle" - if (m_aircraft->groundVehicleType->currentText() == "Turnable (car)" ) { - airframeType = "GroundVehicleCar"; - setupGroundVehicleCar(airframeType); - } else if (m_aircraft->groundVehicleType->currentText() == "Differential (tank)") { - airframeType = "GroundVehicleDifferential"; - setupGroundVehicleDifferential(airframeType); - } else { // "Motorcycle" - airframeType = "GroundVehicleMotorcycle"; - setupGroundVehicleMotorcycle(airframeType); - } + // All airframe types must start with "GroundVehicle" + if (m_aircraft->groundVehicleType->currentText() == "Turnable (car)") { + airframeType = "GroundVehicleCar"; + setupGroundVehicleCar(airframeType); + } else if (m_aircraft->groundVehicleType->currentText() == "Differential (tank)") { + airframeType = "GroundVehicleDifferential"; + setupGroundVehicleDifferential(airframeType); + } else { // "Motorcycle" + airframeType = "GroundVehicleMotorcycle"; + setupGroundVehicleMotorcycle(airframeType); + } - return airframeType; + return airframeType; } - - -/** - Virtual function to refresh the UI widget values - */ -void ConfigGroundVehicleWidget::refreshWidgetsValues(QString frameType) -{ - UAVDataObject* obj; -// UAVObjectField *field; - - GUIConfigDataUnion config = GetConfigData(); - - //THIS SECTION STILL NEEDS WORK. FOR THE MOMENT, USE THE FIXED-WING ONBOARD SETTING IN ORDER TO MINIMIZE CHANCES OF BOLLOXING REAL CODE - // Retrieve channel setup values - setComboCurrentIndex(m_aircraft->gvMotor1ChannelBox, config.ground.GroundVehicleThrottle1); - setComboCurrentIndex(m_aircraft->gvMotor2ChannelBox, config.ground.GroundVehicleThrottle2); - setComboCurrentIndex(m_aircraft->gvSteering1ChannelBox, config.ground.GroundVehicleSteering1); - setComboCurrentIndex(m_aircraft->gvSteering2ChannelBox, config.ground.GroundVehicleSteering2); - - if (frameType == "GroundVehicleDifferential") { - //CURRENTLY BROKEN UNTIL WE DECIDE HOW DIFFERENTIAL SHOULD BEHAVE - // If the vehicle type is "differential", restore the slider setting - - // Find the channel number for Motor1 - obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(obj); - int channel = m_aircraft->gvMotor1ChannelBox->currentIndex()-1; - if (channel > -1) { // If for some reason the actuators were incoherent, we might fail here, hence the check. - - m_aircraft->differentialSteeringSlider1->setValue(getMixerVectorValue(obj,channel,VehicleConfig::MIXERVECTOR_ROLL)*100); - m_aircraft->differentialSteeringSlider2->setValue(getMixerVectorValue(obj,channel,VehicleConfig::MIXERVECTOR_PITCH)*100); - } - } - if (frameType == "GroundVehicleMotorcycle") { - //CURRENTLY BROKEN UNTIL WE DECIDE HOW MOTORCYCLE SHOULD BEHAVE -// obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); -// Q_ASSERT(obj); -// int chMixerNumber = m_aircraft->gvMotor1ChannelBox->currentIndex()-1; -// if (chMixerNumber >=0) { -// field = obj->getField(mixerVectors.at(chMixerNumber)); -// int ti = field->getElementNames().indexOf("Yaw"); -// m_aircraft->differentialSteeringSlider1->setValue(field->getDouble(ti)*100); -// -// ti = field->getElementNames().indexOf("Pitch"); -// m_aircraft->differentialSteeringSlider2->setValue(field->getDouble(ti)*100); -// } - } -} - - /** Setup balancing ground vehicle. Returns False if impossible to create the mixer. */ -bool ConfigGroundVehicleWidget::setupGroundVehicleMotorcycle(QString airframeType){ - // Check coherence: - //Show any config errors in GUI +bool ConfigGroundVehicleWidget::setupGroundVehicleMotorcycle(QString airframeType) +{ + // Check coherence: + // Show any config errors in GUI if (throwConfigError(airframeType)) { - return false; - } + return false; + } - // Now setup the channels: - GUIConfigDataUnion config = GetConfigData(); - ResetActuators(&config); + // Now setup the channels: + GUIConfigDataUnion config = getConfigData(); + resetActuators(&config); config.ground.GroundVehicleThrottle1 = m_aircraft->gvMotor1ChannelBox->currentIndex(); config.ground.GroundVehicleThrottle2 = m_aircraft->gvMotor2ChannelBox->currentIndex(); - SetConfigData(config); - + setConfigData(config); + UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); resetMotorAndServoMixers(mixer); - //motor - int channel = m_aircraft->gvMotor2ChannelBox->currentIndex()-1; + // motor + int channel = m_aircraft->gvMotor2ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127); - //steering - channel = m_aircraft->gvSteering1ChannelBox->currentIndex()-1; + // steering + channel = m_aircraft->gvSteering1ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, -127); - //balance - channel = m_aircraft->gvSteering2ChannelBox->currentIndex()-1; + // balance + channel = m_aircraft->gvSteering2ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, 127); - m_aircraft->gvStatusLabel->setText("Mixer generated"); - + m_aircraft->gvStatusLabel->setText("Mixer generated"); + return true; } - - /** Setup differentially steered ground vehicle. Returns False if impossible to create the mixer. */ -bool ConfigGroundVehicleWidget::setupGroundVehicleDifferential(QString airframeType){ - // Check coherence: - //Show any config errors in GUI +bool ConfigGroundVehicleWidget::setupGroundVehicleDifferential(QString airframeType) +{ + // Check coherence: + // Show any config errors in GUI if (throwConfigError(airframeType)) { - return false; - } + return false; + } // Now setup the channels: - GUIConfigDataUnion config = GetConfigData(); - ResetActuators(&config); - + GUIConfigDataUnion config = getConfigData(); + resetActuators(&config); + config.ground.GroundVehicleThrottle1 = m_aircraft->gvMotor1ChannelBox->currentIndex(); config.ground.GroundVehicleThrottle2 = m_aircraft->gvMotor2ChannelBox->currentIndex(); - SetConfigData((config)); - - UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); + setConfigData(config); + + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); resetMotorAndServoMixers(mixer); - //left motor - int channel = m_aircraft->gvMotor1ChannelBox->currentIndex()-1; + // left motor + int channel = m_aircraft->gvMotor1ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127); - //right motor - channel = m_aircraft->gvMotor2ChannelBox->currentIndex()-1; + // right motor + channel = m_aircraft->gvMotor2ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127); - //Output success message - m_aircraft->gvStatusLabel->setText("Mixer generated"); - + // Output success message + m_aircraft->gvStatusLabel->setText("Mixer generated"); + return true; - } - - /** Setup steerable ground vehicle. @@ -377,45 +404,45 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleDifferential(QString airframeT bool ConfigGroundVehicleWidget::setupGroundVehicleCar(QString airframeType) { // Check coherence: - //Show any config errors in GUI + // Show any config errors in GUI if (throwConfigError(airframeType)) { - return false; - } + return false; + } // Now setup the channels: - GUIConfigDataUnion config = GetConfigData(); - ResetActuators(&config); - + GUIConfigDataUnion config = getConfigData(); + resetActuators(&config); + config.ground.GroundVehicleThrottle1 = m_aircraft->gvMotor1ChannelBox->currentIndex(); config.ground.GroundVehicleThrottle2 = m_aircraft->gvMotor2ChannelBox->currentIndex(); config.ground.GroundVehicleSteering1 = m_aircraft->gvSteering1ChannelBox->currentIndex(); config.ground.GroundVehicleSteering2 = m_aircraft->gvSteering2ChannelBox->currentIndex(); - SetConfigData(config); + setConfigData(config); UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); resetMotorAndServoMixers(mixer); - int channel = m_aircraft->gvSteering1ChannelBox->currentIndex()-1; - setMixerType(mixer,channel, VehicleConfig::MIXERTYPE_SERVO); + int channel = m_aircraft->gvSteering1ChannelBox->currentIndex() - 1; + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127); - channel = m_aircraft->gvSteering2ChannelBox->currentIndex()-1; - setMixerType(mixer,channel, VehicleConfig::MIXERTYPE_SERVO); + channel = m_aircraft->gvSteering2ChannelBox->currentIndex() - 1; + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, -127); - channel = m_aircraft->gvMotor1ChannelBox->currentIndex()-1; - setMixerType(mixer,channel, VehicleConfig::MIXERTYPE_SERVO); + channel = m_aircraft->gvMotor1ChannelBox->currentIndex() - 1; + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); - channel = m_aircraft->gvMotor2ChannelBox->currentIndex()-1; - setMixerType(mixer,channel, VehicleConfig::MIXERTYPE_SERVO); + channel = m_aircraft->gvMotor2ChannelBox->currentIndex() - 1; + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127); - //Output success message + // Output success message m_aircraft->gvStatusLabel->setText("Mixer generated"); - + return true; } @@ -424,94 +451,91 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleCar(QString airframeType) */ bool ConfigGroundVehicleWidget::throwConfigError(QString airframeType) { - //Initialize configuration error flag - bool error=false; + // Initialize configuration error flag + bool error = false; - - //Create a red block. All combo boxes are the same size, so any one should do as a model - int size = m_aircraft->gvEngineChannelBox->style()->pixelMetric(QStyle::PM_SmallIconSize); - QPixmap pixmap(size,size); - pixmap.fill(QColor("red")); - - if (airframeType == "GroundVehicleCar" ) { //Car - if(m_aircraft->gvMotor1ChannelBox->currentText() == "None" && m_aircraft->gvMotor2ChannelBox->currentText() == "None"){ - pixmap.fill(QColor("green")); - m_aircraft->gvMotor1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - m_aircraft->gvMotor2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes -// m_aircraft->gvMotor1Label->setText("" + m_aircraft->gvMotor1Label->text() + ""); -// m_aircraft->gvMotor2Label->setText("" + m_aircraft->gvMotor2Label->text() + ""); - error=true; + // Create a red block. All combo boxes are the same size, so any one should do as a model + int size = m_aircraft->gvEngineChannelBox->style()->pixelMetric(QStyle::PM_SmallIconSize); + QPixmap pixmap(size, size); + pixmap.fill(QColor("red")); - } - else{ - m_aircraft->gvMotor1ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - m_aircraft->gvMotor2ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes -// QTextEdit* htmlText=new QTextEdit(m_aircraft->gvMotor1Label->text()); // HtmlText is any QString with html tags. -// m_aircraft->gvMotor1Label->setText(htmlText->toPlainText()); -// delete htmlText; -// -// htmlText=new QTextEdit(m_aircraft->gvMotor2Label->text()); // HtmlText is any QString with html tags. -// m_aircraft->gvMotor2Label->setText(htmlText->toPlainText()); - } - - if (m_aircraft->gvSteering1ChannelBox->currentText() == "None" && m_aircraft->gvSteering2ChannelBox->currentText() == "None") { - m_aircraft->gvSteering1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - m_aircraft->gvSteering2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes -// m_aircraft->gvStatusLabel->setText("ERROR: check steering channel assignment"); -// m_aircraft->gvSteering1Label->setText("" + m_aircraft->gvSteering1Label->text() + ""); -// m_aircraft->gvSteering2Label->setText("" + m_aircraft->gvSteering2Label->text() + ""); - error=true; - } - else{ - m_aircraft->gvSteering1ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - m_aircraft->gvSteering2ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes -// QTextEdit* htmlText=new QTextEdit(m_aircraft->gvSteering1Label->text()); // HtmlText is any QString with html tags. -// m_aircraft->gvSteering1Label->setText(htmlText->toPlainText()); -// delete htmlText; -// -// htmlText=new QTextEdit(m_aircraft->gvSteering2Label->text()); // HtmlText is any QString with html tags. -// m_aircraft->gvSteering2Label->setText(htmlText->toPlainText()); - } - - } else if (airframeType == "GroundVehicleDifferential"){ //Tank - if(m_aircraft->gvMotor1ChannelBox->currentText() == "None" || m_aircraft->gvMotor2ChannelBox->currentText() == "None"){ - m_aircraft->gvMotor1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - m_aircraft->gvMotor2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else{ - m_aircraft->gvMotor1ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - m_aircraft->gvMotor2ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - - //Always reset - m_aircraft->gvSteering1ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - m_aircraft->gvSteering2ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } else if ( airframeType == "GroundVehicleMotorcycle"){ //Motorcycle - if(m_aircraft->gvMotor1ChannelBox->currentText() == "None" && m_aircraft->gvMotor2ChannelBox->currentText() == "None"){ - m_aircraft->gvMotor2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else{ - m_aircraft->gvMotor2ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - - if (m_aircraft->gvSteering1ChannelBox->currentText() == "None" && m_aircraft->gvSteering2ChannelBox->currentText() == "None") { - m_aircraft->gvSteering1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else{ - m_aircraft->gvSteering1ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - - //Always reset - m_aircraft->gvMotor1ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - m_aircraft->gvSteering2ChannelBox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes - } - - if (error){ - m_aircraft->gvStatusLabel->setText(QString("ERROR: Assign all necessary channels")); - } + if (airframeType == "GroundVehicleCar") { //Car + if (m_aircraft->gvMotor1ChannelBox->currentText() == "None" + && m_aircraft->gvMotor2ChannelBox->currentText() == "None") { + pixmap.fill(QColor("green")); + m_aircraft->gvMotor1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + m_aircraft->gvMotor2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + //m_aircraft->gvMotor1Label->setText("" + m_aircraft->gvMotor1Label->text() + ""); + //m_aircraft->gvMotor2Label->setText("" + m_aircraft->gvMotor2Label->text() + ""); + error = true; + + } else { + m_aircraft->gvMotor1ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + m_aircraft->gvMotor2ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + //QTextEdit* htmlText=new QTextEdit(m_aircraft->gvMotor1Label->text()); // HtmlText is any QString with html tags. + //m_aircraft->gvMotor1Label->setText(htmlText->toPlainText()); + //delete htmlText; + + //htmlText=new QTextEdit(m_aircraft->gvMotor2Label->text()); // HtmlText is any QString with html tags. + //m_aircraft->gvMotor2Label->setText(htmlText->toPlainText()); + } + + if (m_aircraft->gvSteering1ChannelBox->currentText() == "None" + && m_aircraft->gvSteering2ChannelBox->currentText() == "None") { + m_aircraft->gvSteering1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + m_aircraft->gvSteering2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + //m_aircraft->gvStatusLabel->setText("ERROR: check steering channel assignment"); + //m_aircraft->gvSteering1Label->setText("" + m_aircraft->gvSteering1Label->text() + ""); + //m_aircraft->gvSteering2Label->setText("" + m_aircraft->gvSteering2Label->text() + ""); + error = true; + } else { + m_aircraft->gvSteering1ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + m_aircraft->gvSteering2ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + //QTextEdit* htmlText=new QTextEdit(m_aircraft->gvSteering1Label->text()); // HtmlText is any QString with html tags. + //m_aircraft->gvSteering1Label->setText(htmlText->toPlainText()); + //delete htmlText; + + //htmlText=new QTextEdit(m_aircraft->gvSteering2Label->text()); // HtmlText is any QString with html tags. + //m_aircraft->gvSteering2Label->setText(htmlText->toPlainText()); + } + } else if (airframeType == "GroundVehicleDifferential") { //Tank + if (m_aircraft->gvMotor1ChannelBox->currentText() == "None" + || m_aircraft->gvMotor2ChannelBox->currentText() == "None") { + m_aircraft->gvMotor1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + m_aircraft->gvMotor2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + m_aircraft->gvMotor1ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + m_aircraft->gvMotor2ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + + // Always reset + m_aircraft->gvSteering1ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + m_aircraft->gvSteering2ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } else if (airframeType == "GroundVehicleMotorcycle") { //Motorcycle + if (m_aircraft->gvMotor1ChannelBox->currentText() == "None" + && m_aircraft->gvMotor2ChannelBox->currentText() == "None") { + m_aircraft->gvMotor2ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + m_aircraft->gvMotor2ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + + if (m_aircraft->gvSteering1ChannelBox->currentText() == "None" + && m_aircraft->gvSteering2ChannelBox->currentText() == "None") { + m_aircraft->gvSteering1ChannelBox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + m_aircraft->gvSteering1ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + + // Always reset + m_aircraft->gvMotor1ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + m_aircraft->gvSteering2ChannelBox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes + } + + if (error) { + m_aircraft->gvStatusLabel->setText(QString("ERROR: Assign all necessary channels")); + } return error; } - diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.h b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.h index fb6cc48b2..475f54a19 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.h +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.h @@ -27,12 +27,14 @@ #ifndef CONFIGGROUNDVEHICLEWIDGET_H #define CONFIGGROUNDVEHICLEWIDGET_H -#include "ui_airframe.h" +#include "cfg_vehicletypes/vehicleconfig.h" +#include "ui_airframe_ground.h" #include "../uavobjectwidgetutils/configtaskwidget.h" #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" #include "uavobject.h" #include "uavtalk/telemetrymanager.h" + #include #include #include @@ -44,31 +46,28 @@ class ConfigGroundVehicleWidget: public VehicleConfig Q_OBJECT public: - ConfigGroundVehicleWidget(Ui_AircraftWidget *aircraft = 0, QWidget *parent = 0); + static QStringList getChannelDescriptions(); + + ConfigGroundVehicleWidget(QWidget *parent = 0); ~ConfigGroundVehicleWidget(); - friend class ConfigVehicleTypeWidget; + virtual void refreshWidgetsValues(QString frameType); + virtual QString updateConfigObjectsFromWidgets(); private: - Ui_AircraftWidget *m_aircraft; + Ui_GroundConfigWidget *m_aircraft; + + virtual void registerWidgets(ConfigTaskWidget &parent); + virtual void resetActuators(GUIConfigDataUnion *configData); bool setupGroundVehicleCar(QString airframeType); bool setupGroundVehicleDifferential(QString airframeType); bool setupGroundVehicleMotorcycle(QString airframeType); - virtual void ResetActuators(GUIConfigDataUnion* configData); - static QStringList getChannelDescriptions(); - private slots: virtual void setupUI(QString airframeType); - virtual void refreshWidgetsValues(QString frameType); - virtual QString updateConfigObjectsFromWidgets(); virtual bool throwConfigError(QString airframeType); - -protected: - }; - #endif // CONFIGGROUNDVEHICLEWIDGET_H diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.cpp b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.cpp index 7db57f5d1..7fc9d46a5 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.cpp @@ -25,6 +25,10 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configmultirotorwidget.h" +#include "mixersettings.h" +#include "systemsettings.h" +#include "actuatorsettings.h" +#include "actuatorcommand.h" #include #include @@ -37,48 +41,106 @@ #include #include -#include "mixersettings.h" -#include "systemsettings.h" -#include "actuatorsettings.h" -#include "actuatorcommand.h" - - const QString ConfigMultiRotorWidget::CHANNELBOXNAME = QString("multiMotorChannelBox"); - -/** - Constructor - */ -ConfigMultiRotorWidget::ConfigMultiRotorWidget(Ui_AircraftWidget *aircraft, QWidget *parent) : VehicleConfig(parent), invertMotors(1) +QStringList ConfigMultiRotorWidget::getChannelDescriptions() { - m_aircraft = aircraft; + // init a channel_numelem list of channel desc defaults + QStringList channelDesc; + for (int i = 0; i < (int) ConfigMultiRotorWidget::CHANNEL_NUMELEM; i++) { + channelDesc.append(QString("-")); + } + + // get the gui config data + GUIConfigDataUnion configData = getConfigData(); + multiGUISettingsStruct multi = configData.multi; + + if (multi.VTOLMotorN > 0 && multi.VTOLMotorN <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) { + channelDesc[multi.VTOLMotorN - 1] = QString("VTOLMotorN"); + } + if (multi.VTOLMotorNE > 0 && multi.VTOLMotorNE <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) { + channelDesc[multi.VTOLMotorNE - 1] = QString("VTOLMotorNE"); + } + if (multi.VTOLMotorNW > 0 && multi.VTOLMotorNW <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) { + channelDesc[multi.VTOLMotorNW - 1] = QString("VTOLMotorNW"); + } + if (multi.VTOLMotorS > 0 && multi.VTOLMotorS <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) { + channelDesc[multi.VTOLMotorS - 1] = QString("VTOLMotorS"); + } + if (multi.VTOLMotorSE > 0 && multi.VTOLMotorSE <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) { + channelDesc[multi.VTOLMotorSE - 1] = QString("VTOLMotorSE"); + } + if (multi.VTOLMotorSW > 0 && multi.VTOLMotorSW <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) { + channelDesc[multi.VTOLMotorSW - 1] = QString("VTOLMotorSW"); + } + if (multi.VTOLMotorW > 0 && multi.VTOLMotorW <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) { + channelDesc[multi.VTOLMotorW - 1] = QString("VTOLMotorW"); + } + if (multi.VTOLMotorE > 0 && multi.VTOLMotorE <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) { + channelDesc[multi.VTOLMotorE - 1] = QString("VTOLMotorE"); + } + if (multi.TRIYaw > 0 && multi.TRIYaw <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) { + channelDesc[multi.TRIYaw - 1] = QString("Tri-Yaw"); + } + return channelDesc; +} + +ConfigMultiRotorWidget::ConfigMultiRotorWidget(QWidget *parent) : + VehicleConfig(parent), m_aircraft(new Ui_MultiRotorConfigWidget()), invertMotors(false) +{ + m_aircraft->setupUi(this); + + populateChannelComboBoxes(); + + // Setup the Multirotor picture in the Quad settings interface + m_aircraft->quadShape->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_aircraft->quadShape->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + QSvgRenderer *renderer = new QSvgRenderer(); + renderer->load(QString(":/configgadget/images/multirotor-shapes.svg")); + + quad = new QGraphicsSvgItem(); + quad->setSharedRenderer(renderer); + quad->setElementId("quad-x"); + + QGraphicsScene *scene = new QGraphicsScene(); + scene->addItem(quad); + scene->setSceneRect(quad->boundingRect()); + m_aircraft->quadShape->setScene(scene); + + QStringList multiRotorTypes; + multiRotorTypes << "Tricopter Y" << "Quad +" << "Quad X" << "Hexacopter" << "Hexacopter X" << "Hexacopter Y6" + << "Octocopter" << "Octocopter V" << "Octo Coax +" << "Octo Coax X"; + m_aircraft->multirotorFrameType->addItems(multiRotorTypes); + + // Set default model to "Quad X" + m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Quad X")); + + //setupUI(m_aircraft->multirotorFrameType->currentText()); + + connect(m_aircraft->multirotorFrameType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupUI(QString))); + + // Connect the multirotor motor reverse checkbox + connect(m_aircraft->MultirotorRevMixerCheckBox, SIGNAL(clicked(bool)), this, SLOT(reverseMultirotorMotor())); } -/** - Destructor - */ ConfigMultiRotorWidget::~ConfigMultiRotorWidget() { - // Do nothing + delete m_aircraft; } - void ConfigMultiRotorWidget::setupUI(QString frameType) { Q_ASSERT(m_aircraft); - Q_ASSERT(uiowner); Q_ASSERT(quad); - int i; - - // set aircraftType to Multirotor, disable triyaw channel - setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Multirotor")); + // disable triyaw channel m_aircraft->triYawChannelBox->setEnabled(false); // disable all motor channel boxes - for (i=1; i <=8; i++) { + for (int i = 1; i <= 8; i++) { // do it manually so we can turn off any error decorations - QComboBox *combobox = qFindChild(uiowner, "multiMotorChannelBox" + QString::number(i)); + QComboBox *combobox = qFindChild(this, "multiMotorChannelBox" + QString::number(i)); if (combobox) { combobox->setEnabled(false); combobox->setItemData(0, 0, Qt::DecorationRole); @@ -86,198 +148,125 @@ void ConfigMultiRotorWidget::setupUI(QString frameType) } if (frameType == "Tri" || frameType == "Tricopter Y") { - setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Tricopter Y")); + setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Tricopter Y")); - //Enable all necessary motor channel boxes... - enableComboBoxes(uiowner, CHANNELBOXNAME, 3, true); + // Enable all necessary motor channel boxes... + enableComboBoxes(this, CHANNELBOXNAME, 3, true); m_aircraft->mrRollMixLevel->setValue(100); m_aircraft->mrPitchMixLevel->setValue(100); setYawMixLevel(50); m_aircraft->triYawChannelBox->setEnabled(true); - } - else if (frameType == "QuadX" || frameType == "Quad X") { - setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Quad X")); + } else if (frameType == "QuadX" || frameType == "Quad X") { + setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Quad X")); - //Enable all necessary motor channel boxes... - enableComboBoxes(uiowner, CHANNELBOXNAME, 4, true); + // Enable all necessary motor channel boxes... + enableComboBoxes(this, CHANNELBOXNAME, 4, true); // init mixer levels m_aircraft->mrRollMixLevel->setValue(50); m_aircraft->mrPitchMixLevel->setValue(50); setYawMixLevel(50); - } - else if (frameType == "QuadP" || frameType == "Quad +") { - setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Quad +")); + } else if (frameType == "QuadP" || frameType == "Quad +") { + setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Quad +")); - //Enable all necessary motor channel boxes... - enableComboBoxes(uiowner, CHANNELBOXNAME, 4, true); + // Enable all necessary motor channel boxes... + enableComboBoxes(this, CHANNELBOXNAME, 4, true); m_aircraft->mrRollMixLevel->setValue(100); m_aircraft->mrPitchMixLevel->setValue(100); setYawMixLevel(50); - } - else if (frameType == "Hexa" || frameType == "Hexacopter") - { - setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Hexacopter")); + } else if (frameType == "Hexa" || frameType == "Hexacopter") { + setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Hexacopter")); - //Enable all necessary motor channel boxes... - enableComboBoxes(uiowner, CHANNELBOXNAME, 6, true); + // Enable all necessary motor channel boxes... + enableComboBoxes(this, CHANNELBOXNAME, 6, true); m_aircraft->mrRollMixLevel->setValue(50); m_aircraft->mrPitchMixLevel->setValue(33); setYawMixLevel(33); - } - else if (frameType == "HexaX" || frameType == "Hexacopter X" ) { - setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Hexacopter X")); + } else if (frameType == "HexaX" || frameType == "Hexacopter X") { + setComboCurrentIndex(m_aircraft->multirotorFrameType, + m_aircraft->multirotorFrameType->findText("Hexacopter X")); - //Enable all necessary motor channel boxes... - enableComboBoxes(uiowner, CHANNELBOXNAME, 6, true); + // Enable all necessary motor channel boxes... + enableComboBoxes(this, CHANNELBOXNAME, 6, true); m_aircraft->mrRollMixLevel->setValue(33); m_aircraft->mrPitchMixLevel->setValue(50); setYawMixLevel(33); + } else if (frameType == "HexaCoax" || frameType == "Hexacopter Y6") { + setComboCurrentIndex(m_aircraft->multirotorFrameType, + m_aircraft->multirotorFrameType->findText("Hexacopter Y6")); - } - else if (frameType == "HexaCoax" || frameType == "Hexacopter Y6") - { - setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Hexacopter Y6")); - - //Enable all necessary motor channel boxes... - enableComboBoxes(uiowner, CHANNELBOXNAME, 6, true); + // Enable all necessary motor channel boxes... + enableComboBoxes(this, CHANNELBOXNAME, 6, true); m_aircraft->mrRollMixLevel->setValue(100); m_aircraft->mrPitchMixLevel->setValue(50); setYawMixLevel(66); + } else if (frameType == "Octo" || frameType == "Octocopter") { + setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octocopter")); - } - else if (frameType == "Octo" || frameType == "Octocopter") - { - setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octocopter")); - - //Enable all necessary motor channel boxes - enableComboBoxes(uiowner, CHANNELBOXNAME, 8, true); + // Enable all necessary motor channel boxes + enableComboBoxes(this, CHANNELBOXNAME, 8, true); m_aircraft->mrRollMixLevel->setValue(33); m_aircraft->mrPitchMixLevel->setValue(33); setYawMixLevel(25); - } - else if (frameType == "OctoV" || frameType == "Octocopter V") - { - setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octocopter V")); + } else if (frameType == "OctoV" || frameType == "Octocopter V") { + setComboCurrentIndex(m_aircraft->multirotorFrameType, + m_aircraft->multirotorFrameType->findText("Octocopter V")); - //Enable all necessary motor channel boxes - enableComboBoxes(uiowner, CHANNELBOXNAME, 8, true); + // Enable all necessary motor channel boxes + enableComboBoxes(this, CHANNELBOXNAME, 8, true); m_aircraft->mrRollMixLevel->setValue(25); m_aircraft->mrPitchMixLevel->setValue(25); setYawMixLevel(25); + } else if (frameType == "OctoCoaxP" || frameType == "Octo Coax +") { + setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octo Coax +")); - } - else if (frameType == "OctoCoaxP" || frameType == "Octo Coax +") - { - setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octo Coax +")); - - //Enable all necessary motor channel boxes - enableComboBoxes(uiowner, CHANNELBOXNAME, 8, true); + // Enable all necessary motor channel boxes + enableComboBoxes(this, CHANNELBOXNAME, 8, true); m_aircraft->mrRollMixLevel->setValue(100); m_aircraft->mrPitchMixLevel->setValue(100); setYawMixLevel(50); + } else if (frameType == "OctoCoaxX" || frameType == "Octo Coax X") { + setComboCurrentIndex(m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octo Coax X")); - } - else if (frameType == "OctoCoaxX" || frameType == "Octo Coax X") - { - setComboCurrentIndex( m_aircraft->multirotorFrameType, m_aircraft->multirotorFrameType->findText("Octo Coax X")); - - //Enable all necessary motor channel boxes - enableComboBoxes(uiowner, CHANNELBOXNAME, 8, true); + // Enable all necessary motor channel boxes + enableComboBoxes(this, CHANNELBOXNAME, 8, true); m_aircraft->mrRollMixLevel->setValue(50); m_aircraft->mrPitchMixLevel->setValue(50); setYawMixLevel(50); } - //Draw the appropriate airframe - drawAirframe(frameType); + // Draw the appropriate airframe + updateAirframe(frameType); } -void ConfigMultiRotorWidget::drawAirframe(QString frameType){ - - invertMotors = m_aircraft->MultirotorRevMixercheckBox->isChecked() ? -1:1; - - if (frameType == "Tri" || frameType == "Tricopter Y") { - if(invertMotors > 0) - quad->setElementId("tri"); - else - quad->setElementId("tri_reverse"); - } - else if (frameType == "QuadX" || frameType == "Quad X") { - if(invertMotors > 0) - quad->setElementId("quad-x"); - else - quad->setElementId("quad-x_reverse"); - } - else if (frameType == "QuadP" || frameType == "Quad +") { - if(invertMotors > 0) - quad->setElementId("quad-plus"); - else - quad->setElementId("quad-plus_reverse"); - } - else if (frameType == "Hexa" || frameType == "Hexacopter") - { - if(invertMotors > 0) - quad->setElementId("quad-hexa"); - else - quad->setElementId("quad-hexa_reverse"); - } - else if (frameType == "HexaX" || frameType == "Hexacopter X" ) { - if(invertMotors > 0) - quad->setElementId("quad-hexa-H"); - else - quad->setElementId("quad-hexa-H_reverse"); - } - else if (frameType == "HexaCoax" || frameType == "Hexacopter Y6") - { - if(invertMotors > 0) - quad->setElementId("hexa-coax"); - else - quad->setElementId("hexa-coax_reverse"); - } - else if (frameType == "Octo" || frameType == "Octocopter") - { - if(invertMotors > 0) - quad->setElementId("quad-octo"); - else - quad->setElementId("quad-octo_reverse"); - } - else if (frameType == "OctoV" || frameType == "Octocopter V") - { - if(invertMotors > 0) - quad->setElementId("quad-octo-v"); - else - quad->setElementId("quad-octo-v_reverse"); - } - else if (frameType == "OctoCoaxP" || frameType == "Octo Coax +") - { - if(invertMotors > 0) - quad->setElementId("octo-coax-P"); - else - quad->setElementId("octo-coax-P_reverse"); - - } - else if (frameType == "OctoCoaxX" || frameType == "Octo Coax X") - { - if(invertMotors > 0) - quad->setElementId("octo-coax-X"); - else - quad->setElementId("octo-coax-X_reverse"); - - } +void ConfigMultiRotorWidget::registerWidgets(ConfigTaskWidget &parent) { + parent.addWidget(m_aircraft->multiThrottleCurve->getCurveWidget()); + parent.addWidget(m_aircraft->multirotorFrameType); + parent.addWidget(m_aircraft->multiMotorChannelBox1); + parent.addWidget(m_aircraft->multiMotorChannelBox2); + parent.addWidget(m_aircraft->multiMotorChannelBox3); + parent.addWidget(m_aircraft->multiMotorChannelBox4); + parent.addWidget(m_aircraft->multiMotorChannelBox5); + parent.addWidget(m_aircraft->multiMotorChannelBox6); + parent.addWidget(m_aircraft->multiMotorChannelBox7); + parent.addWidget(m_aircraft->multiMotorChannelBox8); + parent.addWidget(m_aircraft->mrPitchMixLevel); + parent.addWidget(m_aircraft->mrRollMixLevel); + parent.addWidget(m_aircraft->mrYawMixLevel); + parent.addWidget(m_aircraft->triYawChannelBox); } -void ConfigMultiRotorWidget::ResetActuators(GUIConfigDataUnion* configData) +void ConfigMultiRotorWidget::resetActuators(GUIConfigDataUnion *configData) { configData->multi.VTOLMotorN = 0; configData->multi.VTOLMotorNE = 0; @@ -290,74 +279,262 @@ void ConfigMultiRotorWidget::ResetActuators(GUIConfigDataUnion* configData) configData->multi.TRIYaw = 0; } -QStringList ConfigMultiRotorWidget::getChannelDescriptions() +/** + Helper function to refresh the UI widget values + */ +void ConfigMultiRotorWidget::refreshWidgetsValues(QString frameType) { - QStringList channelDesc; + Q_ASSERT(m_aircraft); - // init a channel_numelem list of channel desc defaults - for (int i=0; i < (int)(ConfigMultiRotorWidget::CHANNEL_NUMELEM); i++) - { - channelDesc.append(QString("-")); + setupUI(frameType); + + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); + Q_ASSERT(mixer); + + QList curveValues; + getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, &curveValues); + + // is at least one of the curve values != 0? + if (isValidThrottleCurve(&curveValues)) { + // yes, use the curve we just read from mixersettings + m_aircraft->multiThrottleCurve->initCurve(&curveValues); + } else { + // no, init a straight curve + m_aircraft->multiThrottleCurve->initLinearCurve(curveValues.count(), 0.9); } - // get the gui config data - GUIConfigDataUnion configData = GetConfigData(); - multiGUISettingsStruct multi = configData.multi; + GUIConfigDataUnion config = getConfigData(); + multiGUISettingsStruct multi = config.multi; - if (multi.VTOLMotorN > 0 && multi.VTOLMotorN <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) - channelDesc[multi.VTOLMotorN-1] = QString("VTOLMotorN"); - if (multi.VTOLMotorNE > 0 && multi.VTOLMotorNE <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) - channelDesc[multi.VTOLMotorNE-1] = QString("VTOLMotorNE"); - if (multi.VTOLMotorNW > 0 && multi.VTOLMotorNW <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) - channelDesc[multi.VTOLMotorNW-1] = QString("VTOLMotorNW"); - if (multi.VTOLMotorS > 0 && multi.VTOLMotorS <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) - channelDesc[multi.VTOLMotorS-1] = QString("VTOLMotorS"); - if (multi.VTOLMotorSE > 0 && multi.VTOLMotorSE <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) - channelDesc[multi.VTOLMotorSE-1] = QString("VTOLMotorSE"); - if (multi.VTOLMotorSW > 0 && multi.VTOLMotorSW <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) - channelDesc[multi.VTOLMotorSW-1] = QString("VTOLMotorSW"); - if (multi.VTOLMotorW > 0 && multi.VTOLMotorW <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) - channelDesc[multi.VTOLMotorW-1] = QString("VTOLMotorW"); - if (multi.VTOLMotorE > 0 && multi.VTOLMotorE <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) - channelDesc[multi.VTOLMotorE-1] = QString("VTOLMotorE"); - if (multi.TRIYaw > 0 && multi.TRIYaw <= ConfigMultiRotorWidget::CHANNEL_NUMELEM) - channelDesc[multi.TRIYaw-1] = QString("Tri-Yaw"); + if (frameType == "QuadP") { + // Motors 1/2/3/4 are: N / E / S / W + setComboCurrentIndex(m_aircraft->multiMotorChannelBox1, multi.VTOLMotorN); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox2, multi.VTOLMotorE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox3, multi.VTOLMotorS); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox4, multi.VTOLMotorW); - return channelDesc; + // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. + // This assumes that all vectors are identical - if not, the user should use the "custom" setting. + + int channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; + if (channel > -1) { + double value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); + m_aircraft->mrPitchMixLevel->setValue(qRound(value / 1.27)); + + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); + setYawMixLevel(-qRound(value / 1.27)); + + channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); + m_aircraft->mrRollMixLevel->setValue(-qRound(value / 1.27)); + } + } else if (frameType == "QuadX") { + // Motors 1/2/3/4 are: NW / NE / SE / SW + setComboCurrentIndex(m_aircraft->multiMotorChannelBox1, multi.VTOLMotorNW); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox2, multi.VTOLMotorNE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox3, multi.VTOLMotorSE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox4, multi.VTOLMotorSW); + + // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. + // This assumes that all vectors are identical - if not, the user should use the + // "custom" setting. + int channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; + if (channel > -1) { + double value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); + m_aircraft->mrPitchMixLevel->setValue(qRound(value / 1.27)); + + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); + setYawMixLevel(-qRound(value / 1.27)); + + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); + m_aircraft->mrRollMixLevel->setValue(qRound(value / 1.27)); + } + } else if (frameType == "Hexa") { + // Motors 1/2/3 4/5/6 are: N / NE / SE / S / SW / NW + setComboCurrentIndex(m_aircraft->multiMotorChannelBox1, multi.VTOLMotorN); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox2, multi.VTOLMotorNE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox3, multi.VTOLMotorSE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox4, multi.VTOLMotorS); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox5, multi.VTOLMotorSW); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox6, multi.VTOLMotorNW); + + // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. + // This assumes that all vectors are identical - if not, the user should use the + // "custom" setting. + + int channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; + if (channel > -1) { + double value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); + m_aircraft->mrPitchMixLevel->setValue(qRound(value / 1.27)); + + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); + setYawMixLevel(-qRound(value / 1.27)); + + //change channels + channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); + m_aircraft->mrRollMixLevel->setValue(-qRound(value / 1.27)); + } + } else if (frameType == "HexaX") { + // Motors 1/2/3 4/5/6 are: NE / E / SE / SW / W / NW + setComboCurrentIndex(m_aircraft->multiMotorChannelBox1, multi.VTOLMotorNE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox2, multi.VTOLMotorE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox3, multi.VTOLMotorSE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox4, multi.VTOLMotorSW); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox5, multi.VTOLMotorW); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox6, multi.VTOLMotorNW); + + // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. + // This assumes that all vectors are identical - if not, the user should use the + // "custom" setting. + + int channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; + if (channel > -1) { + double value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); + m_aircraft->mrPitchMixLevel->setValue(qRound(value / 1.27)); + + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); + setYawMixLevel(-qRound(value / 1.27)); + + channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); + m_aircraft->mrRollMixLevel->setValue(-qRound(value / 1.27)); + } + } else if (frameType == "HexaCoax") { + // Motors 1/2/3 4/5/6 are: NW/W NE/E S/SE + setComboCurrentIndex(m_aircraft->multiMotorChannelBox1, multi.VTOLMotorNW); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox2, multi.VTOLMotorW); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox3, multi.VTOLMotorNE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox4, multi.VTOLMotorE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox5, multi.VTOLMotorS); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox6, multi.VTOLMotorSE); + + // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. + // This assumes that all vectors are identical - if not, the user should use the + // "custom" setting. + int channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; + if (channel > -1) { + double value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); + m_aircraft->mrPitchMixLevel->setValue(qRound(2 * value / 1.27)); + + channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); + setYawMixLevel(qRound(value / 1.27)); + + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); + m_aircraft->mrRollMixLevel->setValue(qRound(value / 1.27)); + } + } else if (frameType == "Octo" || frameType == "OctoV" || frameType == "OctoCoaxP") { + // Motors 1 to 8 are N / NE / E / etc + setComboCurrentIndex(m_aircraft->multiMotorChannelBox1, multi.VTOLMotorN); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox2, multi.VTOLMotorNE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox3, multi.VTOLMotorE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox4, multi.VTOLMotorSE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox5, multi.VTOLMotorS); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox6, multi.VTOLMotorSW); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox7, multi.VTOLMotorW); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox8, multi.VTOLMotorNW); + + // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. + // This assumes that all vectors are identical - if not, the user should use the + // "custom" setting. + int channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; + if (channel > -1) { + if (frameType == "Octo") { + double value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); + m_aircraft->mrPitchMixLevel->setValue(qRound(value / 1.27)); + + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); + setYawMixLevel(-qRound(value / 1.27)); + + //change channels + channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); + m_aircraft->mrRollMixLevel->setValue(-qRound(value / 1.27)); + } else if (frameType == "OctoV") { + double value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); + m_aircraft->mrPitchMixLevel->setValue(qRound(value / 1.27)); + + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); + setYawMixLevel(-qRound(value / 1.27)); + + //change channels + channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); + m_aircraft->mrRollMixLevel->setValue(-qRound(value / 1.27)); + } else if (frameType == "OctoCoaxP") { + double value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); + m_aircraft->mrPitchMixLevel->setValue(qRound(value / 1.27)); + + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); + setYawMixLevel(-qRound(value / 1.27)); + + //change channels + channel = m_aircraft->multiMotorChannelBox3->currentIndex() - 1; + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); + m_aircraft->mrRollMixLevel->setValue(-qRound(value / 1.27)); + } + } + } else if (frameType == "OctoCoaxX") { + // Motors 1 to 8 are N / NE / E / etc + setComboCurrentIndex(m_aircraft->multiMotorChannelBox1, multi.VTOLMotorNW); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox2, multi.VTOLMotorN); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox3, multi.VTOLMotorNE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox4, multi.VTOLMotorE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox5, multi.VTOLMotorSE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox6, multi.VTOLMotorS); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox7, multi.VTOLMotorSW); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox8, multi.VTOLMotorW); + + // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. + // This assumes that all vectors are identical - if not, the user should use the + // "custom" setting. + int channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; + if (channel > -1) { + double value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); + m_aircraft->mrPitchMixLevel->setValue(qRound(value / 1.27)); + + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); + setYawMixLevel(-qRound(value / 1.27)); + + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); + m_aircraft->mrRollMixLevel->setValue(qRound(value / 1.27)); + } + } else if (frameType == "Tri") { + // Motors 1 to 8 are N / NE / E / etc + setComboCurrentIndex(m_aircraft->multiMotorChannelBox1, multi.VTOLMotorNW); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox2, multi.VTOLMotorNE); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox3, multi.VTOLMotorS); + setComboCurrentIndex(m_aircraft->multiMotorChannelBox4, multi.VTOLMotorS); + setComboCurrentIndex(m_aircraft->triYawChannelBox, multi.TRIYaw); + + int channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; + if (channel > -1) { + double value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); + m_aircraft->mrPitchMixLevel->setValue(qRound(2 * value / 1.27)); + + value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); + m_aircraft->mrRollMixLevel->setValue(qRound(value / 1.27)); + + } + } + + updateAirframe(frameType); } -void ConfigMultiRotorWidget::setYawMixLevel(int value) -{ - if(value<0) - { - m_aircraft->mrYawMixLevel->setValue((-1)*value); - m_aircraft->MultirotorRevMixercheckBox->setChecked(true); - } - else - { - m_aircraft->mrYawMixLevel->setValue(value); - m_aircraft->MultirotorRevMixercheckBox->setChecked(false); - } - -} - - - - /** Helper function to update the UI widget objects */ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets() { - QString airframeType; - QList motorList; - - UAVDataObject* mixerObj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(mixerObj); + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); + Q_ASSERT(mixer); // Curve is also common to all quads: - setThrottleCurve(mixerObj, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->multiThrottleCurve->getCurve() ); + setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->multiThrottleCurve->getCurve() ); + QString airframeType; + QList motorList; if (m_aircraft->multirotorFrameType->currentText() == "Quad +") { airframeType = "QuadP"; setupQuad(true); @@ -373,135 +550,134 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets() } else if (m_aircraft->multirotorFrameType->currentText() == "Hexacopter Y6") { airframeType = "HexaCoax"; - //Show any config errors in GUI + // Show any config errors in GUI if (throwConfigError(6)) { return airframeType; } - motorList << "VTOLMotorNW" << "VTOLMotorW" << "VTOLMotorNE" << "VTOLMotorE" - << "VTOLMotorS" << "VTOLMotorSE"; + motorList << "VTOLMotorNW" << "VTOLMotorW" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorS" << "VTOLMotorSE"; setupMotors(motorList); // Motor 1 to 6, Y6 Layout: // pitch roll yaw - double mixer [8][3] = { - { 0.5, 1, -1}, - { 0.5, 1, 1}, - { 0.5, -1, -1}, - { 0.5, -1, 1}, - { -1, 0, -1}, - { -1, 0, 1}, - { 0, 0, 0}, - { 0, 0, 0} + double mixerMatrix[8][3] = { + { 0.5, 1, -1 }, + { 0.5, 1, 1 }, + { 0.5, -1, -1 }, + { 0.5, -1, 1 }, + { -1, 0, -1 }, + { -1, 0, 1 }, + { 0, 0, 0 }, + { 0, 0, 0 } }; - setupMultiRotorMixer(mixer); + setupMultiRotorMixer(mixerMatrix); m_aircraft->mrStatusLabel->setText("Configuration OK"); } else if (m_aircraft->multirotorFrameType->currentText() == "Octocopter") { airframeType = "Octo"; - //Show any config errors in GUI + // Show any config errors in GUI if (throwConfigError(8)) { return airframeType; } - motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" - << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW"; + motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW" + << "VTOLMotorW" << "VTOLMotorNW"; setupMotors(motorList); // Motor 1 to 8: // pitch roll yaw - double mixer [8][3] = { - { 1, 0, -1}, - { 1, -1, 1}, - { 0, -1, -1}, - { -1, -1, 1}, - { -1, 0, -1}, - { -1, 1, 1}, - { 0, 1, -1}, - { 1, 1, 1} + double mixerMatrix[8][3] = { + { 1, 0, -1 }, + { 1, -1, 1 }, + { 0, -1, -1 }, + { -1, -1, 1 }, + { -1, 0, -1 }, + { -1, 1, 1 }, + { 0, 1, -1 }, + { 1, 1, 1 } }; - setupMultiRotorMixer(mixer); + setupMultiRotorMixer(mixerMatrix); m_aircraft->mrStatusLabel->setText("Configuration OK"); } else if (m_aircraft->multirotorFrameType->currentText() == "Octocopter V") { airframeType = "OctoV"; - //Show any config errors in GUI + // Show any config errors in GUI if (throwConfigError(8)) { return airframeType; } - motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" - << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW"; + motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW" + << "VTOLMotorW" << "VTOLMotorNW"; setupMotors(motorList); // Motor 1 to 8: // IMPORTANT: Assumes evenly spaced engines // pitch roll yaw - double mixer [8][3] = { - { 0.33, -1, -1}, - { 1 , -1, 1}, - { -1 , -1, -1}, - { -0.33, -1, 1}, - { -0.33, 1, -1}, - { -1 , 1, 1}, - { 1 , 1, -1}, - { 0.33, 1, 1} + double mixerMatrix[8][3] = { + { 0.33, -1, -1 }, + { 1 , -1, 1 }, + { -1 , -1, -1 }, + { -0.33, -1, 1 }, + { -0.33, 1, -1 }, + { -1 , 1, 1 }, + { 1 , 1, -1 }, + { 0.33, 1, 1 } }; - setupMultiRotorMixer(mixer); + setupMultiRotorMixer(mixerMatrix); m_aircraft->mrStatusLabel->setText("Configuration OK"); } else if (m_aircraft->multirotorFrameType->currentText() == "Octo Coax +") { airframeType = "OctoCoaxP"; - //Show any config errors in GUI + // Show any config errors in GUI if (throwConfigError(8)) { return airframeType; } - motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" - << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW"; + motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW" + << "VTOLMotorW" << "VTOLMotorNW"; setupMotors(motorList); // Motor 1 to 8: // pitch roll yaw - double mixer [8][3] = { - { 1, 0, -1}, - { 1, 0, 1}, - { 0, -1, -1}, - { 0, -1, 1}, - { -1, 0, -1}, - { -1, 0, 1}, - { 0, 1, -1}, - { 0, 1, 1} + double mixerMatrix[8][3] = { + { 1, 0, -1 }, + { 1, 0, 1 }, + { 0, -1, -1 }, + { 0, -1, 1 }, + { -1, 0, -1 }, + { -1, 0, 1 }, + { 0, 1, -1 }, + { 0, 1, 1 } }; - setupMultiRotorMixer(mixer); + setupMultiRotorMixer(mixerMatrix); m_aircraft->mrStatusLabel->setText("Configuration OK"); } else if (m_aircraft->multirotorFrameType->currentText() == "Octo Coax X") { airframeType = "OctoCoaxX"; - //Show any config errors in GUI + // Show any config errors in GUI if (throwConfigError(8)) { return airframeType; } - motorList << "VTOLMotorNW" << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" - << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW"; + motorList << "VTOLMotorNW" << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorS" + << "VTOLMotorSW" << "VTOLMotorW"; setupMotors(motorList); // Motor 1 to 8: // pitch roll yaw - double mixer [8][3] = { - { 1, 1, -1}, - { 1, 1, 1}, - { 1, -1, -1}, - { 1, -1, 1}, - { -1, -1, -1}, - { -1, -1, 1}, - { -1, 1, -1}, - { -1, 1, 1} + double mixerMatrix[8][3] = { + { 1, 1, -1 }, + { 1, 1, 1 }, + { 1, -1, -1 }, + { 1, -1, 1 }, + { -1, -1, -1 }, + { -1, -1, 1 }, + { -1, 1, -1 }, + { -1, 1, 1 } }; - setupMultiRotorMixer(mixer); + setupMultiRotorMixer(mixerMatrix); m_aircraft->mrStatusLabel->setText("Configuration OK"); } else if (m_aircraft->multirotorFrameType->currentText() == "Tricopter Y") { airframeType = "Tri"; - //Show any config errors in GUI + // Show any config errors in GUI if (throwConfigError(3)) { return airframeType; @@ -513,31 +689,30 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets() motorList << "VTOLMotorNW" << "VTOLMotorNE" << "VTOLMotorS"; setupMotors(motorList); - GUIConfigDataUnion config = GetConfigData(); + GUIConfigDataUnion config = getConfigData(); config.multi.TRIYaw = m_aircraft->triYawChannelBox->currentIndex(); - SetConfigData(config); - + setConfigData(config); // Motor 1 to 6, Y6 Layout: // pitch roll yaw - double mixer [8][3] = { - { 0.5, 1, 0}, - { 0.5, -1, 0}, - { -1, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0}, - { 0, 0, 0} + double mixerMatrix[8][3] = { + { 0.5, 1, 0 }, + { 0.5, -1, 0 }, + { -1, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 } }; - setupMultiRotorMixer(mixer); + setupMultiRotorMixer(mixerMatrix); - //tell the mixer about tricopter yaw channel + // tell the mixer about tricopter yaw channel - int channel = m_aircraft->triYawChannelBox->currentIndex()-1; - if (channel > -1){ - setMixerType(mixerObj, channel, VehicleConfig::MIXERTYPE_SERVO); - setMixerVectorValue(mixerObj, channel, VehicleConfig::MIXERVECTOR_YAW, 127); + int channel = m_aircraft->triYawChannelBox->currentIndex() - 1; + if (channel > -1) { + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO); + setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127); } m_aircraft->mrStatusLabel->setText(tr("Configuration OK")); @@ -547,278 +722,61 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets() return airframeType; } - - -/** - Helper function to refresh the UI widget values - */ -void ConfigMultiRotorWidget::refreshWidgetsValues(QString frameType) +void ConfigMultiRotorWidget::setYawMixLevel(int value) { - int channel; - double value; - - GUIConfigDataUnion config = GetConfigData(); - multiGUISettingsStruct multi = config.multi; - - UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(mixer); - - if (frameType == "QuadP") - { - // Motors 1/2/3/4 are: N / E / S / W - setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorN); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorS); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorW); - - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - - channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; - if (channel > -1) - { - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); - m_aircraft->mrPitchMixLevel->setValue( qRound(value/1.27) ); - - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); - setYawMixLevel( -qRound(value/1.27) ); - - channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); - m_aircraft->mrRollMixLevel->setValue( -qRound(value/1.27)); - - } - } - else if (frameType == "QuadX") - { - // Motors 1/2/3/4 are: NW / NE / SE / SW - setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorNW); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorNE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorSE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorSW); - - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; - if (channel > -1) - { - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); - m_aircraft->mrPitchMixLevel->setValue( qRound(value/1.27) ); - - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); - setYawMixLevel( -qRound(value/1.27) ); - - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); - m_aircraft->mrRollMixLevel->setValue( qRound(value/1.27)); - - } - - } - else if (frameType == "Hexa") - { - // Motors 1/2/3 4/5/6 are: N / NE / SE / S / SW / NW - - setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorN); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorNE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorSE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorS); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox5,multi.VTOLMotorSW); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox6,multi.VTOLMotorNW); - - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - - channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; - if (channel > -1) - { - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); - m_aircraft->mrPitchMixLevel->setValue( qRound(value/1.27) ); - - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); - setYawMixLevel( -qRound(value/1.27) ); - - //change channels - channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); - m_aircraft->mrRollMixLevel->setValue( -qRound(value/1.27) ); - - } - - - } - else if (frameType == "HexaX") - { - // Motors 1/2/3 4/5/6 are: NE / E / SE / SW / W / NW - - setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorNE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorSE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorSW); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox5,multi.VTOLMotorW); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox6,multi.VTOLMotorNW); - - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - - channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; - if (channel > -1) - { - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); - m_aircraft->mrPitchMixLevel->setValue( qRound(value/1.27) ); - - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); - setYawMixLevel( -qRound(value/1.27) ); - - channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); - m_aircraft->mrRollMixLevel->setValue( -qRound(value/1.27) ); - } - } - else if (frameType == "HexaCoax") - { - // Motors 1/2/3 4/5/6 are: NW/W NE/E S/SE - - setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorNW); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorW); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorNE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox5,multi.VTOLMotorS); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox6,multi.VTOLMotorSE); - - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; - if (channel > -1) - { - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); - m_aircraft->mrPitchMixLevel->setValue( qRound(2*value/1.27) ); - - channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); - setYawMixLevel( qRound(value/1.27) ); - - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); - m_aircraft->mrRollMixLevel->setValue( qRound(value/1.27) ); - } - } - else if (frameType == "Octo" || frameType == "OctoV" || frameType == "OctoCoaxP") - { - // Motors 1 to 8 are N / NE / E / etc - - setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorN); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorNE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorSE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox5,multi.VTOLMotorS); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox6,multi.VTOLMotorSW); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox7,multi.VTOLMotorW); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox8,multi.VTOLMotorNW); - - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; - if (channel > -1) - { - if (frameType == "Octo") { - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); - m_aircraft->mrPitchMixLevel->setValue( qRound(value/1.27) ); - - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); - setYawMixLevel( -qRound(value/1.27) ); - - //change channels - channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); - m_aircraft->mrRollMixLevel->setValue( -qRound(value/1.27) ); - } - else if (frameType == "OctoV") { - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); - m_aircraft->mrPitchMixLevel->setValue( qRound(value/1.27) ); - - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); - setYawMixLevel( -qRound(value/1.27) ); - - //change channels - channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); - m_aircraft->mrRollMixLevel->setValue( -qRound(value/1.27) ); - } - else if (frameType == "OctoCoaxP") { - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); - m_aircraft->mrPitchMixLevel->setValue( qRound(value/1.27) ); - - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); - setYawMixLevel( -qRound(value/1.27) ); - - //change channels - channel = m_aircraft->multiMotorChannelBox3->currentIndex() - 1; - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); - m_aircraft->mrRollMixLevel->setValue( -qRound(value/1.27) ); - } - - } - } - else if (frameType == "OctoCoaxX") - { - // Motors 1 to 8 are N / NE / E / etc - - setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorNW); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorN); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorNE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox5,multi.VTOLMotorSE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox6,multi.VTOLMotorS); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox7,multi.VTOLMotorSW); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox8,multi.VTOLMotorW); - - // Now, read the 1st mixer R/P/Y levels and initialize the mix sliders. - // This assumes that all vectors are identical - if not, the user should use the - // "custom" setting. - channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; - if (channel > -1) - { - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); - m_aircraft->mrPitchMixLevel->setValue( qRound(value/1.27) ); - - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); - setYawMixLevel( -qRound(value/1.27) ); - - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); - m_aircraft->mrRollMixLevel->setValue( qRound(value/1.27) ); - } - } - else if (frameType == "Tri") - { - // Motors 1 to 8 are N / NE / E / etc - - setComboCurrentIndex(m_aircraft->multiMotorChannelBox1,multi.VTOLMotorNW); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox2,multi.VTOLMotorNE); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox3,multi.VTOLMotorS); - setComboCurrentIndex(m_aircraft->multiMotorChannelBox4,multi.VTOLMotorS); - setComboCurrentIndex(m_aircraft->triYawChannelBox,multi.TRIYaw); - - channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1; - if (channel > -1) - { - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH); - m_aircraft->mrPitchMixLevel->setValue( qRound(2*value/1.27) ); - - value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); - m_aircraft->mrRollMixLevel->setValue( qRound(value/1.27) ); - - } + if (value < 0) { + m_aircraft->mrYawMixLevel->setValue(-value); + m_aircraft->MultirotorRevMixerCheckBox->setChecked(true); + } else { + m_aircraft->mrYawMixLevel->setValue(value); + m_aircraft->MultirotorRevMixerCheckBox->setChecked(false); } - drawAirframe(frameType); } +void ConfigMultiRotorWidget::reverseMultirotorMotor(){ + QString frameType = m_aircraft->multirotorFrameType->currentText(); + updateAirframe(frameType); +} +void ConfigMultiRotorWidget::updateAirframe(QString frameType) +{ + qDebug() << "ConfigMultiRotorWidget::updateAirframe - frame type" << frameType; + + QString elementId; + if (frameType == "Tri" || frameType == "Tricopter Y") { + elementId = "tri"; + } else if (frameType == "QuadX" || frameType == "Quad X") { + elementId = "quad-x"; + } else if (frameType == "QuadP" || frameType == "Quad +") { + elementId = "quad-plus"; + } else if (frameType == "Hexa" || frameType == "Hexacopter") { + elementId = "quad-hexa"; + } else if (frameType == "HexaX" || frameType == "Hexacopter X") { + elementId = "quad-hexa-H"; + } else if (frameType == "HexaCoax" || frameType == "Hexacopter Y6") { + elementId = "hexa-coax"; + } else if (frameType == "Octo" || frameType == "Octocopter") { + elementId = "quad-octo"; + } else if (frameType == "OctoV" || frameType == "Octocopter V") { + elementId = "quad-octo-v"; + } else if (frameType == "OctoCoaxP" || frameType == "Octo Coax +") { + elementId = "octo-coax-P"; + } else if (frameType == "OctoCoaxX" || frameType == "Octo Coax X") { + elementId = "octo-coax-X"; + } + + invertMotors = m_aircraft->MultirotorRevMixerCheckBox->isChecked(); + if (invertMotors) { + elementId += "_reverse"; + } + + if (elementId != "" && elementId != quad->elementId()) { + quad->setElementId(elementId); + m_aircraft->quadShape->setSceneRect(quad->boundingRect()); + m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); + } +} /** Helper function: setupQuadMotor @@ -832,54 +790,48 @@ void ConfigMultiRotorWidget::setupQuadMotor(int channel, double pitch, double ro setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 0); - setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, roll*127); - setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, pitch*127); - setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, yaw*127); + setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL, roll * 127); + setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH, pitch * 127); + setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, yaw * 127); } - - /** Helper function: setup motors. Takes a list of channel names in input. */ void ConfigMultiRotorWidget::setupMotors(QList motorList) { QList mmList; - mmList << m_aircraft->multiMotorChannelBox1 << m_aircraft->multiMotorChannelBox2 << m_aircraft->multiMotorChannelBox3 - << m_aircraft->multiMotorChannelBox4 << m_aircraft->multiMotorChannelBox5 << m_aircraft->multiMotorChannelBox6 - << m_aircraft->multiMotorChannelBox7 << m_aircraft->multiMotorChannelBox8; + mmList << m_aircraft->multiMotorChannelBox1 << m_aircraft->multiMotorChannelBox2 + << m_aircraft->multiMotorChannelBox3 << m_aircraft->multiMotorChannelBox4 + << m_aircraft->multiMotorChannelBox5 << m_aircraft->multiMotorChannelBox6 + << m_aircraft->multiMotorChannelBox7 << m_aircraft->multiMotorChannelBox8; - GUIConfigDataUnion configData = GetConfigData(); - ResetActuators(&configData); + GUIConfigDataUnion configData = getConfigData(); + resetActuators(&configData); - int index; foreach (QString motor, motorList) { - - index = mmList.takeFirst()->currentIndex(); - - if (motor == QString("VTOLMotorN")) + int index = mmList.takeFirst()->currentIndex(); + if (motor == QString("VTOLMotorN")) { configData.multi.VTOLMotorN = index; - else if (motor == QString("VTOLMotorNE")) + } else if (motor == QString("VTOLMotorNE")) { configData.multi.VTOLMotorNE = index; - else if (motor == QString("VTOLMotorE")) + } else if (motor == QString("VTOLMotorE")) { configData.multi.VTOLMotorE = index; - else if (motor == QString("VTOLMotorSE")) + } else if (motor == QString("VTOLMotorSE")) { configData.multi.VTOLMotorSE = index; - else if (motor == QString( "VTOLMotorS")) + } else if (motor == QString("VTOLMotorS")) { configData.multi.VTOLMotorS = index; - else if (motor == QString( "VTOLMotorSW")) + } else if (motor == QString("VTOLMotorSW")) { configData.multi.VTOLMotorSW = index; - else if (motor == QString( "VTOLMotorW")) + } else if (motor == QString("VTOLMotorW")) { configData.multi.VTOLMotorW = index; - else if (motor == QString( "VTOLMotorNW")) + } else if (motor == QString("VTOLMotorNW")) { configData.multi.VTOLMotorNW = index; + } } - SetConfigData(configData); - + setConfigData(configData); } - - /** Set up a Quad-X or Quad-P mixer */ @@ -887,19 +839,16 @@ bool ConfigMultiRotorWidget::setupQuad(bool pLayout) { // Check coherence: - //Show any config errors in GUI + // Show any config errors in GUI if (throwConfigError(4)) { return false; } - QList motorList; if (pLayout) { - motorList << "VTOLMotorN" << "VTOLMotorE" << "VTOLMotorS" - << "VTOLMotorW"; + motorList << "VTOLMotorN" << "VTOLMotorE" << "VTOLMotorS" << "VTOLMotorW"; } else { - motorList << "VTOLMotorNW" << "VTOLMotorNE" << "VTOLMotorSE" - << "VTOLMotorSW"; + motorList << "VTOLMotorNW" << "VTOLMotorNE" << "VTOLMotorSE" << "VTOLMotorSW"; } setupMotors(motorList); @@ -920,7 +869,7 @@ bool ConfigMultiRotorWidget::setupQuad(bool pLayout) { 0, 0, 0}, { 0, 0, 0} }; - // + // Motor 1 to 4, P Layout: // pitch roll yaw // {1 ,0 ,-0.5 //Front motor (CW) @@ -947,25 +896,22 @@ bool ConfigMultiRotorWidget::setupQuad(bool pLayout) return true; } - - /** Set up a Hexa-X or Hexa-P mixer */ bool ConfigMultiRotorWidget::setupHexa(bool pLayout) { // Check coherence: - //Show any config errors in GUI - if (throwConfigError(6)) + // Show any config errors in GUI + if (throwConfigError(6)) { return false; + } QList motorList; if (pLayout) { - motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorSE" - << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorNW"; + motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorSE" << "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorNW"; } else { - motorList << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" - << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW"; + motorList << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE" << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW"; } setupMotors(motorList); @@ -979,7 +925,6 @@ bool ConfigMultiRotorWidget::setupHexa(bool pLayout) // 4 {-0.3 , 0 , 0.3 // S CCW // 5 {-0.3 , 0.5 ,-0.3 // SW CW // 6 { 0.3 , 0.5 , 0.3 // NW CCW - double pMixer [8][3] = { { 1, 0, -1}, { 1, -1, 1}, @@ -991,7 +936,6 @@ bool ConfigMultiRotorWidget::setupHexa(bool pLayout) { 0, 0, 0} }; - // // Motor 1 to 6, X Layout: // 1 [ 0.5, -0.3, -0.3 ] NE // 2 [ 0 , -0.3, 0.3 ] E @@ -1025,64 +969,82 @@ bool ConfigMultiRotorWidget::setupHexa(bool pLayout) */ bool ConfigMultiRotorWidget::setupMultiRotorMixer(double mixerFactors[8][3]) { - QList mmList; - mmList << m_aircraft->multiMotorChannelBox1 << m_aircraft->multiMotorChannelBox2 << m_aircraft->multiMotorChannelBox3 - << m_aircraft->multiMotorChannelBox4 << m_aircraft->multiMotorChannelBox5 << m_aircraft->multiMotorChannelBox6 - << m_aircraft->multiMotorChannelBox7 << m_aircraft->multiMotorChannelBox8; - UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); resetMotorAndServoMixers(mixer); // and enable only the relevant channels: - double pFactor = (double)m_aircraft->mrPitchMixLevel->value()/100; - double rFactor = (double)m_aircraft->mrRollMixLevel->value()/100; - invertMotors = m_aircraft->MultirotorRevMixercheckBox->isChecked() ? -1:1; - double yFactor =invertMotors * (double)m_aircraft->mrYawMixLevel->value()/100; - for (int i=0 ; i<8; i++) { - if(mmList.at(i)->isEnabled()) - { - int channel = mmList.at(i)->currentIndex()-1; - if (channel > -1) - setupQuadMotor(channel, mixerFactors[i][0]*pFactor, - rFactor*mixerFactors[i][1], yFactor*mixerFactors[i][2]); + double pFactor = (double) m_aircraft->mrPitchMixLevel->value() / 100.0; + double rFactor = (double) m_aircraft->mrRollMixLevel->value() / 100.0; + invertMotors = m_aircraft->MultirotorRevMixerCheckBox->isChecked(); + double yFactor = (invertMotors ? -1.0 : 1.0) * (double) m_aircraft->mrYawMixLevel->value() / 100.0; + + QList mmList; + mmList << m_aircraft->multiMotorChannelBox1 << m_aircraft->multiMotorChannelBox2 + << m_aircraft->multiMotorChannelBox3 << m_aircraft->multiMotorChannelBox4 + << m_aircraft->multiMotorChannelBox5 << m_aircraft->multiMotorChannelBox6 + << m_aircraft->multiMotorChannelBox7 << m_aircraft->multiMotorChannelBox8; + for (int i = 0; i < 8; i++) { + if (mmList.at(i)->isEnabled()) { + int channel = mmList.at(i)->currentIndex() - 1; + if (channel > -1) { + setupQuadMotor(channel, mixerFactors[i][0] * pFactor, rFactor * mixerFactors[i][1], + yFactor * mixerFactors[i][2]); + } } } return true; } - /** This function displays text and color formatting in order to help the user understand what channels have not yet been configured. */ bool ConfigMultiRotorWidget::throwConfigError(int numMotors) -{ - //Initialize configuration error flag - bool error=false; +{ + // Initialize configuration error flag + bool error = false; - //Iterate through all instances of multiMotorChannelBox - for (int i=0; i(uiowner, "multiMotorChannelBox" + QString::number(i+1)); - if (combobox){ + QComboBox *combobox = qFindChild(this, "multiMotorChannelBox" + QString::number(i + 1)); + if (combobox) { if (combobox->currentText() == "None") { int size = combobox->style()->pixelMetric(QStyle::PM_SmallIconSize); - QPixmap pixmap(size,size); + QPixmap pixmap(size, size); pixmap.fill(QColor("red")); - combobox->setItemData(0, pixmap, Qt::DecorationRole);//Set color palettes - error=true; - } - else { - combobox->setItemData(0, 0, Qt::DecorationRole);//Reset color palettes + combobox->setItemData(0, pixmap, Qt::DecorationRole); //Set color palettes + error = true; + } else { + combobox->setItemData(0, 0, Qt::DecorationRole); //Reset color palettes } } } - - if (error){ - m_aircraft->mrStatusLabel->setText(QString("ERROR: Assign all %1 motor channels").arg(numMotors)); + if (error) { + m_aircraft->mrStatusLabel->setText( + QString("ERROR: Assign all %1 motor channels").arg(numMotors)); } return error; } +/** + WHAT DOES THIS DO??? + */ +void ConfigMultiRotorWidget::showEvent(QShowEvent *event) +{ + Q_UNUSED(event) + // Thit fitInView method should only be called now, once the + // widget is shown, otherwise it cannot compute its values and + // the result is usually a ahrsbargraph that is way too small. + m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); +} +/** + Resize the GUI contents when the user changes the window size + */ +void ConfigMultiRotorWidget::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); +} diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.h b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.h index 4ce10aae3..9361c0755 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.h +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configmultirotorwidget.h @@ -27,17 +27,17 @@ #ifndef CONFIGMULTIROTORWIDGET_H #define CONFIGMULTIROTORWIDGET_H -#include "ui_airframe.h" -#include "../uavobjectwidgetutils/configtaskwidget.h" #include "cfg_vehicletypes/vehicleconfig.h" - +#include "ui_airframe_multirotor.h" +#include "../uavobjectwidgetutils/configtaskwidget.h" #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" #include "uavobject.h" #include "uavtalk/telemetrymanager.h" + +#include #include -#include -#include +#include class Ui_Widget; @@ -46,16 +46,26 @@ class ConfigMultiRotorWidget: public VehicleConfig Q_OBJECT public: - ConfigMultiRotorWidget(Ui_AircraftWidget *aircraft = 0, QWidget *parent = 0); + static const QString CHANNELBOXNAME; + static QStringList getChannelDescriptions(); + + ConfigMultiRotorWidget(QWidget *parent = 0); ~ConfigMultiRotorWidget(); - friend class ConfigVehicleTypeWidget; + virtual void refreshWidgetsValues(QString frameType); + virtual QString updateConfigObjectsFromWidgets(); + +protected: + void showEvent(QShowEvent *event); + void resizeEvent(QResizeEvent *event); private: - Ui_AircraftWidget *m_aircraft; - - QWidget *uiowner; + Ui_MultiRotorConfigWidget *m_aircraft; QGraphicsSvgItem *quad; + bool invertMotors; + + virtual void registerWidgets(ConfigTaskWidget &parent); + virtual void resetActuators(GUIConfigDataUnion *configData); bool setupQuad(bool pLayout); bool setupHexa(bool pLayout); @@ -64,28 +74,15 @@ private: void setupMotors(QList motorList); void setupQuadMotor(int channel, double roll, double pitch, double yaw); - float invertMotors; - - virtual void ResetActuators(GUIConfigDataUnion* configData); - static QStringList getChannelDescriptions(); - static const QString CHANNELBOXNAME; void setYawMixLevel(int); - void drawAirframe(QString multiRotorType); + void updateAirframe(QString multiRotorType); private slots: virtual void setupUI(QString airframeType); - virtual void refreshWidgetsValues(QString frameType); - virtual QString updateConfigObjectsFromWidgets(); virtual bool throwConfigError(int numMotors); - -protected: - -signals: - void configurationChanged(); - + void reverseMultirotorMotor(); }; - #endif // CONFIGMULTIROTORWIDGET_H diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.cpp b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.cpp index 64ab037c8..e70ee0835 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.cpp +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.cpp @@ -29,29 +29,27 @@ #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" #include "uavobject.h" - #include "systemsettings.h" #include VehicleConfig::VehicleConfig(QWidget *parent) : ConfigTaskWidget(parent) { - //Generate lists of mixerTypeNames, mixerVectorNames, channelNames + // Generate lists of mixerTypeNames, mixerVectorNames, channelNames channelNames << "None"; - for (int i = 0; i < (int)(VehicleConfig::CHANNEL_NUMELEM); i++) { - mixerTypes << QString("Mixer%1Type").arg(i+1); - mixerVectors << QString("Mixer%1Vector").arg(i+1); - channelNames << QString("Channel%1").arg(i+1); + for (int i = 0; i < (int) VehicleConfig::CHANNEL_NUMELEM; i++) { + mixerTypes << QString("Mixer%1Type").arg(i + 1); + mixerVectors << QString("Mixer%1Vector").arg(i + 1); + channelNames << QString("Channel%1").arg(i + 1); } - mixerTypeDescriptions << "Disabled" << "Motor" << "Servo" << "CameraRoll" << "CameraPitch" - << "CameraYaw" << "Accessory0" << "Accessory1" << "Accessory2" - << "Accessory3" << "Accessory4" << "Accessory5"; + mixerTypeDescriptions << "Disabled" << "Motor" << "Servo" << "CameraRoll" << "CameraPitch" << "CameraYaw" + << "Accessory0" << "Accessory1" << "Accessory2" << "Accessory3" << "Accessory4" << "Accessory5"; // This is needed because new style tries to compact things as much as possible in grid // and on OSX the widget sizes of PushButtons is reported incorrectly: // https://bugreports.qt-project.org/browse/QTBUG-14591 - foreach( QPushButton * btn, findChildren() ) { + foreach(QPushButton *btn, findChildren()) { btn->setAttribute(Qt::WA_LayoutUsesWidgetRect); } } @@ -61,52 +59,91 @@ VehicleConfig::~VehicleConfig() // Do nothing } -GUIConfigDataUnion VehicleConfig::GetConfigData() { - - int i; - GUIConfigDataUnion configData; - +GUIConfigDataUnion VehicleConfig::getConfigData() +{ // get an instance of systemsettings - SystemSettings * systemSettings = SystemSettings::GetInstance(getUAVObjectManager()); + SystemSettings *systemSettings = SystemSettings::GetInstance(getUAVObjectManager()); Q_ASSERT(systemSettings); SystemSettings::DataFields systemSettingsData = systemSettings->getData(); // copy systemsettings -> local configData - for(i = 0; i < (int)(SystemSettings::GUICONFIGDATA_NUMELEM); i++) - configData.UAVObject[i]=systemSettingsData.GUIConfigData[i]; + GUIConfigDataUnion configData; + for (int i = 0; i < (int) SystemSettings::GUICONFIGDATA_NUMELEM; i++) { + configData.UAVObject[i] = systemSettingsData.GUIConfigData[i]; + } // sanity check - Q_ASSERT(SystemSettings::GUICONFIGDATA_NUMELEM == - (sizeof(configData.UAVObject) / sizeof(configData.UAVObject[0]))); + Q_ASSERT(SystemSettings::GUICONFIGDATA_NUMELEM == (sizeof(configData.UAVObject) / sizeof(configData.UAVObject[0]))); return configData; } -void VehicleConfig::SetConfigData(GUIConfigDataUnion configData) { - - int i; - +void VehicleConfig::setConfigData(GUIConfigDataUnion configData) +{ // sanity check - Q_ASSERT(SystemSettings::GUICONFIGDATA_NUMELEM == - (sizeof(configData.UAVObject) / sizeof(configData.UAVObject[0]))); + Q_ASSERT(SystemSettings::GUICONFIGDATA_NUMELEM == (sizeof(configData.UAVObject) / sizeof(configData.UAVObject[0]))); // get an instance of systemsettings - SystemSettings * systemSettings = SystemSettings::GetInstance(getUAVObjectManager()); + SystemSettings *systemSettings = SystemSettings::GetInstance(getUAVObjectManager()); Q_ASSERT(systemSettings); SystemSettings::DataFields systemSettingsData = systemSettings->getData(); - UAVObjectField* guiConfig = systemSettings->getField("GUIConfigData"); + UAVObjectField *guiConfig = systemSettings->getField("GUIConfigData"); Q_ASSERT(guiConfig); - if(!guiConfig) + if (!guiConfig) { return; + } // copy parameter configData -> systemsettings - for (i = 0; i < (int)(SystemSettings::GUICONFIGDATA_NUMELEM); i++) + for (int i = 0; i < (int) SystemSettings::GUICONFIGDATA_NUMELEM; i++) { guiConfig->setValue(configData.UAVObject[i], i); + } } -void VehicleConfig::ResetActuators(GUIConfigDataUnion* configData) +void VehicleConfig::setupUI(QString frameType) { + Q_UNUSED(frameType); +} + +void VehicleConfig::refreshWidgetsValues(QString frameType) +{ + Q_UNUSED(frameType); +} + +QString VehicleConfig::updateConfigObjectsFromWidgets() +{ + return NULL; +} + +void VehicleConfig::refreshWidgetsValues(UAVObject *o) +{ + Q_UNUSED(o); +} + +void VehicleConfig::updateObjectsFromWidgets() +{ + +} + +void VehicleConfig::resetActuators(GUIConfigDataUnion *configData) +{ + Q_UNUSED(configData); +} + + +void VehicleConfig::registerWidgets(ConfigTaskWidget &parent) { + Q_UNUSED(parent); +} + +// NEW STYLE: Loop through the widgets looking for all widgets that have "ChannelBox" in their name +// The upshot of this is that ALL new ComboBox widgets for selecting the output channel must have "ChannelBox" in their name +// FOR WHATEVER REASON, THIS DOES NOT WORK WITH ChannelBox. ChannelBo is sufficiently accurate +void VehicleConfig::populateChannelComboBoxes() +{ + QList l = findChildren(QRegExp("\\S+ChannelBo\\S+")); + foreach(QComboBox *combobox, l) { + combobox->addItems(channelNames); + } } /** @@ -114,44 +151,48 @@ void VehicleConfig::ResetActuators(GUIConfigDataUnion* configData) Sets the current index on supplied combobox to index if it is within bounds 0 <= index < combobox.count() */ -void VehicleConfig::setComboCurrentIndex(QComboBox* box, int index) +void VehicleConfig::setComboCurrentIndex(QComboBox *box, int index) { Q_ASSERT(box); - - if (index >= 0 && index < box->count()) + if (index >= 0 && index < box->count()) { box->setCurrentIndex(index); + } } /** Helper function: - enables/disables the named comboboxes within supplied uiowner + enables/disables the named comboboxes within supplied owner */ -void VehicleConfig::enableComboBoxes(QWidget* owner, QString boxName, int boxCount, bool enable) +void VehicleConfig::enableComboBoxes(QWidget *owner, QString boxName, int boxCount, bool enable) { for (int i = 1; i <= boxCount; i++) { QComboBox* box = qFindChild(owner, QString("%0%1").arg(boxName).arg(i)); - if (box) + if (box) { box->setEnabled(enable); + } } } -QString VehicleConfig::getMixerType(UAVDataObject* mixer, int channel) + +QString VehicleConfig::getMixerType(UAVDataObject *mixer, int channel) { Q_ASSERT(mixer); - QString mixerType = mixerTypeDescriptions[0]; //default to disabled + // default to disabled + QString mixerType = mixerTypeDescriptions[0]; if (channel >= 0 && channel < mixerTypes.count()) { UAVObjectField *field = mixer->getField(mixerTypes.at(channel)); Q_ASSERT(field); - if (field) - mixerType = field->getValue().toString(); + if (field) { + mixerType = field->getValue().toString(); + } } return mixerType; } -void VehicleConfig::setMixerType(UAVDataObject* mixer, int channel, MixerTypeElem mixerType) +void VehicleConfig::setMixerType(UAVDataObject *mixer, int channel, MixerTypeElem mixerType) { Q_ASSERT(mixer); @@ -160,15 +201,14 @@ void VehicleConfig::setMixerType(UAVDataObject* mixer, int channel, MixerTypeEle Q_ASSERT(field); if (field) { - if (mixerType >= 0 && mixerType < mixerTypeDescriptions.count()) - { + if (mixerType >= 0 && mixerType < mixerTypeDescriptions.count()) { field->setValue(mixerTypeDescriptions[mixerType]); } } } } -void VehicleConfig::resetMixerVector(UAVDataObject* mixer, int channel) +void VehicleConfig::resetMixerVector(UAVDataObject *mixer, int channel) { Q_ASSERT(mixer); @@ -184,7 +224,7 @@ void VehicleConfig::resetMixerVector(UAVDataObject* mixer, int channel) // Disable all servo/motor mixers (but keep camera and accessory ones) void VehicleConfig::resetMotorAndServoMixers(UAVDataObject *mixer) { - for (int channel = 0; channel < (int)VehicleConfig::CHANNEL_NUMELEM; channel++) { + for (int channel = 0; channel < (int) VehicleConfig::CHANNEL_NUMELEM; channel++) { QString type = getMixerType(mixer, channel); if ((type == "Disabled") || (type == "Motor") || (type == "Servo")) { setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_DISABLED); @@ -193,12 +233,10 @@ void VehicleConfig::resetMotorAndServoMixers(UAVDataObject *mixer) } } -double VehicleConfig::getMixerVectorValue(UAVDataObject* mixer, int channel, MixerVectorElem elementName) +double VehicleConfig::getMixerVectorValue(UAVDataObject *mixer, int channel, MixerVectorElem elementName) { Q_ASSERT(mixer); - double value = 0; - if (channel >= 0 && channel < mixerVectors.count()) { UAVObjectField *field = mixer->getField(mixerVectors.at(channel)); Q_ASSERT(field); @@ -210,7 +248,7 @@ double VehicleConfig::getMixerVectorValue(UAVDataObject* mixer, int channel, Mix return value; } -void VehicleConfig::setMixerVectorValue(UAVDataObject* mixer, int channel, MixerVectorElem elementName, double value) +void VehicleConfig::setMixerVectorValue(UAVDataObject *mixer, int channel, MixerVectorElem elementName, double value) { Q_ASSERT(mixer); @@ -224,7 +262,7 @@ void VehicleConfig::setMixerVectorValue(UAVDataObject* mixer, int channel, Mixer } } -double VehicleConfig::getMixerValue(UAVDataObject* mixer, QString elementName) +double VehicleConfig::getMixerValue(UAVDataObject *mixer, QString elementName) { Q_ASSERT(mixer); @@ -237,7 +275,7 @@ double VehicleConfig::getMixerValue(UAVDataObject* mixer, QString elementName) return value; } -void VehicleConfig::setMixerValue(UAVDataObject* mixer, QString elementName, double value) +void VehicleConfig::setMixerValue(UAVDataObject *mixer, QString elementName, double value) { Q_ASSERT(mixer); @@ -247,67 +285,56 @@ void VehicleConfig::setMixerValue(UAVDataObject* mixer, QString elementName, dou } } - -void VehicleConfig::setThrottleCurve(UAVDataObject* mixer, MixerThrottleCurveElem curveType, QList curve) +void VehicleConfig::setThrottleCurve(UAVDataObject *mixer, MixerThrottleCurveElem curveType, QList curve) { QPointer field; - switch (curveType) - { - case MIXER_THROTTLECURVE1: - { - field = mixer->getField("ThrottleCurve1"); - break; - } - case MIXER_THROTTLECURVE2: - { - field = mixer->getField("ThrottleCurve2"); - break; - } + switch (curveType) { + case MIXER_THROTTLECURVE1: + field = mixer->getField("ThrottleCurve1"); + break; + case MIXER_THROTTLECURVE2: + field = mixer->getField("ThrottleCurve2"); + break; } - if (field && field->getNumElements() == curve.length()) { - for (int i=0;isetValue(curve.at(i),i); + if (field && (field->getNumElements() == (unsigned int) curve.length())) { + for (int i = 0; i < curve.length(); i++) { + field->setValue(curve.at(i), i); } } } -void VehicleConfig::getThrottleCurve(UAVDataObject* mixer, MixerThrottleCurveElem curveType, QList* curve) +void VehicleConfig::getThrottleCurve(UAVDataObject *mixer, MixerThrottleCurveElem curveType, QList *curve) { Q_ASSERT(mixer); Q_ASSERT(curve); QPointer field; - switch (curveType) - { - case MIXER_THROTTLECURVE1: - { - field = mixer->getField("ThrottleCurve1"); - break; - } - case MIXER_THROTTLECURVE2: - { - field = mixer->getField("ThrottleCurve2"); - break; - } + switch (curveType) { + case MIXER_THROTTLECURVE1: + field = mixer->getField("ThrottleCurve1"); + break; + case MIXER_THROTTLECURVE2: + field = mixer->getField("ThrottleCurve2"); + break; } if (field) { curve->clear(); - for (unsigned int i=0; i < field->getNumElements(); i++) { + for (unsigned int i = 0; i < field->getNumElements(); i++) { curve->append(field->getValue(i).toDouble()); } } } -bool VehicleConfig::isValidThrottleCurve(QList* curve) +bool VehicleConfig::isValidThrottleCurve(QList *curve) { Q_ASSERT(curve); if (curve) { - for (int i=0; i < curve->count(); i++) { + for (int i = 0; i < curve->count(); i++) { if (curve->at(i) != 0) return true; } @@ -315,41 +342,44 @@ bool VehicleConfig::isValidThrottleCurve(QList* curve) return false; } -double VehicleConfig::getCurveMin(QList* curve) +double VehicleConfig::getCurveMin(QList *curve) { + // TODO initialize to max double double min = 0; - for (int i=0; icount(); i++) + for (int i = 0; i < curve->count(); i++) { min = std::min(min, curve->at(i)); - + } return min; } -double VehicleConfig::getCurveMax(QList* curve) +double VehicleConfig::getCurveMax(QList *curve) { + // TODO initialize to min double double max = 0; - for (int i=0; icount(); i++) + for (int i = 0; i < curve->count(); i++) { max = std::max(max, curve->at(i)); - + } return max; } + /** Reset the contents of a field */ void VehicleConfig::resetField(UAVObjectField * field) { - for (unsigned int i=0;igetNumElements();i++) { - field->setValue(0,i); + for (unsigned int i = 0; i < field->getNumElements(); i++) { + field->setValue(0, i); } } - /** * Util function to get a pointer to the object manager * @return pointer to the UAVObjectManager */ -UAVObjectManager* VehicleConfig::getUAVObjectManager() { +UAVObjectManager *VehicleConfig::getUAVObjectManager() +{ ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - UAVObjectManager * objMngr = pm->getObject(); + UAVObjectManager *objMngr = pm->getObject(); Q_ASSERT(objMngr); return objMngr; } diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.h b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.h index 3b729a6dd..f116d05b9 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.h +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/vehicleconfig.h @@ -24,8 +24,8 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef GUIVEHICLECONFIG_H -#define GUIVEHICLECONFIG_H +#ifndef VEHICLECONFIG_H +#define VEHICLECONFIG_H #include "../uavobjectwidgetutils/configtaskwidget.h" #include "extensionsystem/pluginmanager.h" @@ -33,7 +33,6 @@ #include "uavobject.h" #include "actuatorcommand.h" - typedef struct { uint VTOLMotorN:4; uint VTOLMotorS:4; @@ -42,11 +41,11 @@ typedef struct { uint VTOLMotorNW:4; uint VTOLMotorNE:4; uint VTOLMotorSW:4; - uint VTOLMotorSE:4; //32bits + uint VTOLMotorSE:4; // 32 bits uint TRIYaw:4; - quint32 padding:28; //64bits + quint32 padding:28; // 64 bits quint32 padding1; - quint32 padding2; //128bits + quint32 padding2; // 128 bits } __attribute__((packed)) multiGUISettingsStruct; typedef struct { @@ -58,15 +57,15 @@ typedef struct { uint ccpmLinkRollState:1; uint SliderValue0:7; uint SliderValue1:7; - uint SliderValue2:7;//41bits + uint SliderValue2:7; // 41 bits uint ServoIndexW:4; uint ServoIndexX:4; uint ServoIndexY:4; - uint ServoIndexZ:4;//57bits + uint ServoIndexZ:4; // 57 bits uint Throttle:4; - uint Tail:4; //65bits - quint32 padding:31; //96bits - quint32 padding1; //128bits + uint Tail:4; // 65bits + quint32 padding:31; // 96 bits + quint32 padding1; // 128 bits } __attribute__((packed)) heliGUISettingsStruct; typedef struct { @@ -77,10 +76,10 @@ typedef struct { uint FixedWingPitch2:4; uint FixedWingYaw1:4; uint FixedWingYaw2:4; - uint padding:4; //32bits + uint padding:4; // 32 bits quint32 padding1; quint32 padding2; - quint32 padding3; //128bits + quint32 padding3; // 128 bits } __attribute__((packed)) fixedGUISettingsStruct; typedef struct { @@ -88,78 +87,119 @@ typedef struct { uint GroundVehicleThrottle2:4; uint GroundVehicleSteering1:4; uint GroundVehicleSteering2:4; - uint padding:16; //32bits + uint padding:16; // 32 bits quint32 padding1; quint32 padding2; - quint32 padding3; //128bits + quint32 padding3; // 128 bits } __attribute__((packed)) groundGUISettingsStruct; typedef union { - uint UAVObject[4]; //32bits * 4 - heliGUISettingsStruct heli; //128bits - fixedGUISettingsStruct fixedwing; - multiGUISettingsStruct multi; + uint UAVObject[4]; // 32 bits * 4 + heliGUISettingsStruct heli; // 128 bits + fixedGUISettingsStruct fixedwing; + multiGUISettingsStruct multi; groundGUISettingsStruct ground; } GUIConfigDataUnion; +class ConfigTaskWidget; +/* + * This class handles vehicle specific configuration UI and associated logic. + * + * This class derives from ConfigTaskWidget and overrides its the default "binding" mechanism. + * It does not use the "dirty" state management directlyand registers its relevant widgets with ConfigTaskWidget to do so. + */ class VehicleConfig: public ConfigTaskWidget { - Q_OBJECT +Q_OBJECT - public: - VehicleConfig(QWidget *parent = 0); - ~VehicleConfig(); +public: - /* Enumeration options for ThrottleCurves */ - typedef enum { MIXER_THROTTLECURVE1=0, MIXER_THROTTLECURVE2=1 } MixerThrottleCurveElem; + /* Enumeration options for ThrottleCurves */ + typedef enum { + MIXER_THROTTLECURVE1 = 0, MIXER_THROTTLECURVE2 = 1 + } MixerThrottleCurveElem; - /* Enumeration options for field MixerType */ - typedef enum { MIXERTYPE_DISABLED=0, MIXERTYPE_MOTOR=1, MIXERTYPE_SERVO=2, MIXERTYPE_CAMERAROLL=3, MIXERTYPE_CAMERAPITCH=4, MIXERTYPE_CAMERAYAW=5, MIXERTYPE_ACCESSORY0=6, MIXERTYPE_ACCESSORY1=7, MIXERTYPE_ACCESSORY2=8, MIXERTYPE_ACCESSORY3=9, MIXERTYPE_ACCESSORY4=10, MIXERTYPE_ACCESSORY5=11 } MixerTypeElem; - /* Array element names for field MixerVector */ - typedef enum { MIXERVECTOR_THROTTLECURVE1=0, MIXERVECTOR_THROTTLECURVE2=1, MIXERVECTOR_ROLL=2, MIXERVECTOR_PITCH=3, MIXERVECTOR_YAW=4 } MixerVectorElem; + /* Enumeration options for field MixerType */ + typedef enum { + MIXERTYPE_DISABLED = 0, + MIXERTYPE_MOTOR = 1, + MIXERTYPE_SERVO = 2, + MIXERTYPE_CAMERAROLL = 3, + MIXERTYPE_CAMERAPITCH = 4, + MIXERTYPE_CAMERAYAW = 5, + MIXERTYPE_ACCESSORY0 = 6, + MIXERTYPE_ACCESSORY1 = 7, + MIXERTYPE_ACCESSORY2 = 8, + MIXERTYPE_ACCESSORY3 = 9, + MIXERTYPE_ACCESSORY4 = 10, + MIXERTYPE_ACCESSORY5 = 11 + } MixerTypeElem; - static GUIConfigDataUnion GetConfigData(); - static void SetConfigData(GUIConfigDataUnion configData); - static void resetField(UAVObjectField * field); - static void setComboCurrentIndex(QComboBox* box, int index); - static void enableComboBoxes(QWidget* owner, QString boxName, int boxCount, bool enable); - double getMixerVectorValue(UAVDataObject* mixer, int channel, MixerVectorElem elementName); - void setMixerVectorValue(UAVDataObject* mixer, int channel, MixerVectorElem elementName, double value); - void resetMixerVector(UAVDataObject* mixer, int channel); - void resetMotorAndServoMixers(UAVDataObject* mixer); - QString getMixerType(UAVDataObject* mixer, int channel); - void setMixerType(UAVDataObject* mixer, int channel, MixerTypeElem mixerType); - double getMixerValue(UAVDataObject* mixer, QString elementName); - void setMixerValue(UAVDataObject* mixer, QString elementName, double value); - void setThrottleCurve(UAVDataObject* mixer, MixerThrottleCurveElem curveType, QList curve); - void getThrottleCurve(UAVDataObject* mixer, MixerThrottleCurveElem curveType, QList* curve); - bool isValidThrottleCurve(QList* curve); - double getCurveMin(QList* curve); - double getCurveMax(QList* curve); - virtual void ResetActuators(GUIConfigDataUnion* configData); + /* Array element names for field MixerVector */ + typedef enum { + MIXERVECTOR_THROTTLECURVE1 = 0, + MIXERVECTOR_THROTTLECURVE2 = 1, + MIXERVECTOR_ROLL = 2, + MIXERVECTOR_PITCH = 3, + MIXERVECTOR_YAW = 4 + } MixerVectorElem; - QStringList channelNames; - QStringList mixerTypes; - QStringList mixerVectors; - QStringList mixerTypeDescriptions; + static const quint32 CHANNEL_NUMELEM = ActuatorCommand::CHANNEL_NUMELEM;; - static const quint32 CHANNEL_NUMELEM = ActuatorCommand::CHANNEL_NUMELEM; + static GUIConfigDataUnion getConfigData(); + static void setConfigData(GUIConfigDataUnion configData); - private: + static void resetField(UAVObjectField *field); - static UAVObjectManager* getUAVObjectManager(); + static void setComboCurrentIndex(QComboBox *box, int index); + static void enableComboBoxes(QWidget *owner, QString boxName, int boxCount, bool enable); - private slots: + // VehicleConfig class + VehicleConfig(QWidget *parent = 0); + ~VehicleConfig(); - public slots: + virtual void registerWidgets(ConfigTaskWidget &parent); - signals: - //void ConfigurationChanged(); + virtual void refreshWidgetsValues(QString frameType); + virtual QString updateConfigObjectsFromWidgets(); + + double getMixerValue(UAVDataObject *mixer, QString elementName); + void setMixerValue(UAVDataObject *mixer, QString elementName, double value); protected: + QStringList channelNames; + QStringList mixerTypes; + QStringList mixerVectors; + QStringList mixerTypeDescriptions; + + void populateChannelComboBoxes(); + + double getMixerVectorValue(UAVDataObject *mixer, int channel, MixerVectorElem elementName); + void setMixerVectorValue(UAVDataObject *mixer, int channel, MixerVectorElem elementName, double value); + void resetMixerVector(UAVDataObject *mixer, int channel); + void resetMotorAndServoMixers(UAVDataObject *mixer); + QString getMixerType(UAVDataObject *mixer, int channel); + void setMixerType(UAVDataObject *mixer, int channel, MixerTypeElem mixerType); + void setThrottleCurve(UAVDataObject *mixer, MixerThrottleCurveElem curveType, QList curve); + void getThrottleCurve(UAVDataObject *mixer, MixerThrottleCurveElem curveType, QList* curve); + bool isValidThrottleCurve(QList *curve); + double getCurveMin(QList *curve); + double getCurveMax(QList *curve); + +protected slots: + virtual void refreshWidgetsValues(UAVObject *o = NULL); + virtual void updateObjectsFromWidgets(); + +private: + static UAVObjectManager *getUAVObjectManager(); + + virtual void resetActuators(GUIConfigDataUnion *configData); + +private slots: + virtual void setupUI(QString airframeType); }; -#endif // GUIVEHICLECONFIG_H +#endif // VEHICLECONFIG_H diff --git a/ground/openpilotgcs/src/plugins/config/config.pro b/ground/openpilotgcs/src/plugins/config/config.pro index 1f9d797c4..af016c2ac 100644 --- a/ground/openpilotgcs/src/plugins/config/config.pro +++ b/ground/openpilotgcs/src/plugins/config/config.pro @@ -18,7 +18,6 @@ HEADERS += configplugin.h \ config_cc_hw_widget.h \ configccattitudewidget.h \ configpipxtremewidget.h \ - cfg_vehicletypes/configccpmwidget.h \ configstabilizationwidget.h \ assertions.h \ calibration.h \ @@ -28,10 +27,12 @@ HEADERS += configplugin.h \ configcamerastabilizationwidget.h \ configtxpidwidget.h \ outputchannelform.h \ - cfg_vehicletypes/configmultirotorwidget.h \ - cfg_vehicletypes/configgroundvehiclewidget.h \ - cfg_vehicletypes/configfixedwingwidget.h \ cfg_vehicletypes/vehicleconfig.h \ + cfg_vehicletypes/configccpmwidget.h \ + cfg_vehicletypes/configmultirotorwidget.h \ + cfg_vehicletypes/configfixedwingwidget.h \ + cfg_vehicletypes/configgroundvehiclewidget.h \ + cfg_vehicletypes/configcustomwidget.h \ configrevowidget.h \ config_global.h \ mixercurve.h \ @@ -60,19 +61,24 @@ SOURCES += configplugin.cpp \ configcamerastabilizationwidget.cpp \ configrevowidget.cpp \ configtxpidwidget.cpp \ - cfg_vehicletypes/configmultirotorwidget.cpp \ - cfg_vehicletypes/configgroundvehiclewidget.cpp \ - cfg_vehicletypes/configfixedwingwidget.cpp \ - cfg_vehicletypes/configccpmwidget.cpp \ - outputchannelform.cpp \ cfg_vehicletypes/vehicleconfig.cpp \ + cfg_vehicletypes/configccpmwidget.cpp \ + cfg_vehicletypes/configmultirotorwidget.cpp \ + cfg_vehicletypes/configfixedwingwidget.cpp \ + cfg_vehicletypes/configgroundvehiclewidget.cpp \ + cfg_vehicletypes/configcustomwidget.cpp \ + outputchannelform.cpp \ mixercurve.cpp \ dblspindelegate.cpp \ configrevohwwidget.cpp FORMS += airframe.ui \ + airframe_ccpm.ui \ + airframe_fixedwing.ui \ + airframe_ground.ui \ + airframe_multirotor.ui \ + airframe_custom.ui \ cc_hw_settings.ui \ - ccpm.ui \ stabilization.ui \ input.ui \ output.ui \ diff --git a/ground/openpilotgcs/src/plugins/config/configgadget.qrc b/ground/openpilotgcs/src/plugins/config/configgadget.qrc index a5b006745..adffc9568 100644 --- a/ground/openpilotgcs/src/plugins/config/configgadget.qrc +++ b/ground/openpilotgcs/src/plugins/config/configgadget.qrc @@ -3,7 +3,6 @@ images/help2.png images/ahrs-calib.svg images/paper-plane.svg - images/curve-bg.svg images/multirotor-shapes.svg images/ccpm_setup.svg images/PipXtreme.png diff --git a/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.cpp b/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.cpp index dd290073a..f22d84214 100644 --- a/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.cpp @@ -25,77 +25,81 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "configvehicletypewidget.h" +#include "systemsettings.h" +#include "actuatorsettings.h" + +#include "cfg_vehicletypes/configccpmwidget.h" +#include "cfg_vehicletypes/configfixedwingwidget.h" +#include "cfg_vehicletypes/configgroundvehiclewidget.h" +#include "cfg_vehicletypes/configmultirotorwidget.h" +#include "cfg_vehicletypes/configcustomwidget.h" #include #include #include #include -#include -#include -#include -#include #include #include -#include -#include "systemsettings.h" -#include "mixersettings.h" -#include "actuatorsettings.h" #include #include - /** - Helper delegate for the custom mixer editor table. - Taken straight from Qt examples, thanks! + Static function to get currently assigned channelDescriptions + for all known vehicle types; instantiates the appropriate object + then asks it to supply channel descs */ -SpinBoxDelegate::SpinBoxDelegate(QObject *parent) - : QItemDelegate(parent) - { - } - -QWidget *SpinBoxDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem &/* option */, - const QModelIndex &/* index */) const +QStringList ConfigVehicleTypeWidget::getChannelDescriptions() { - QSpinBox *editor = new QSpinBox(parent); - editor->setMinimum(-127); - editor->setMaximum(127); + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); + UAVObjectManager *objMngr = pm->getObject(); + Q_ASSERT(objMngr); - return editor; + // get an instance of systemsettings + SystemSettings *systemSettings = SystemSettings::GetInstance(objMngr); + Q_ASSERT(systemSettings); + SystemSettings::DataFields systemSettingsData = systemSettings->getData(); + + QStringList channelDesc; + switch (systemSettingsData.AirframeType) { + case SystemSettings::AIRFRAMETYPE_FIXEDWING: + case SystemSettings::AIRFRAMETYPE_FIXEDWINGELEVON: + case SystemSettings::AIRFRAMETYPE_FIXEDWINGVTAIL: + // fixed wing + channelDesc = ConfigFixedWingWidget::getChannelDescriptions(); + break; + case SystemSettings::AIRFRAMETYPE_HELICP: + // helicp + channelDesc = ConfigCcpmWidget::getChannelDescriptions(); + break; + case SystemSettings::AIRFRAMETYPE_VTOL: + case SystemSettings::AIRFRAMETYPE_TRI: + case SystemSettings::AIRFRAMETYPE_QUADX: + case SystemSettings::AIRFRAMETYPE_QUADP: + case SystemSettings::AIRFRAMETYPE_OCTOV: + case SystemSettings::AIRFRAMETYPE_OCTOCOAXX: + case SystemSettings::AIRFRAMETYPE_OCTOCOAXP: + case SystemSettings::AIRFRAMETYPE_OCTO: + case SystemSettings::AIRFRAMETYPE_HEXAX: + case SystemSettings::AIRFRAMETYPE_HEXACOAX: + case SystemSettings::AIRFRAMETYPE_HEXA: + // multirotor + channelDesc = ConfigMultiRotorWidget::getChannelDescriptions(); + break; + case SystemSettings::AIRFRAMETYPE_GROUNDVEHICLECAR: + case SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEDIFFERENTIAL: + case SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEMOTORCYCLE: + // ground + channelDesc = ConfigGroundVehicleWidget::getChannelDescriptions(); + break; + default: + channelDesc = ConfigCustomWidget::getChannelDescriptions(); + break; + } + + return channelDesc; } -void SpinBoxDelegate::setEditorData(QWidget *editor, - const QModelIndex &index) const -{ - int value = index.model()->data(index, Qt::EditRole).toInt(); - - QSpinBox *spinBox = static_cast(editor); - spinBox->setValue(value); -} - -void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const -{ - QSpinBox *spinBox = static_cast(editor); - spinBox->interpretText(); - int value = spinBox->value(); - - model->setData(index, value, Qt::EditRole); -} - -void SpinBoxDelegate::updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, const QModelIndex &/* index */) const -{ - editor->setGeometry(option.rect); -} - -/**********************************************************************************/ - - -/** - Constructor - */ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_aircraft = new Ui_AircraftWidget(); @@ -103,10 +107,11 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi ExtensionSystem::PluginManager *pm=ExtensionSystem::PluginManager::instance(); Core::Internal::GeneralSettings * settings=pm->getObject(); - if(!settings->useExpertMode()) + if (!settings->useExpertMode()) { m_aircraft->saveAircraftToRAM->setVisible(false); + } - addApplySaveButtons(m_aircraft->saveAircraftToRAM,m_aircraft->saveAircraftToSD); + addApplySaveButtons(m_aircraft->saveAircraftToRAM, m_aircraft->saveAircraftToSD); addUAVObject("SystemSettings"); addUAVObject("MixerSettings"); @@ -115,120 +120,40 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi ffTuningInProgress = false; ffTuningPhase = false; - //Generate lists of mixerTypeNames, mixerVectorNames, channelNames - channelNames << "None"; - for (int i = 0; i < (int)ActuatorSettings::CHANNELADDR_NUMELEM; i++) { - - mixerTypes << QString("Mixer%1Type").arg(i+1); - mixerVectors << QString("Mixer%1Vector").arg(i+1); - channelNames << QString("Channel%1").arg(i+1); - } - QStringList airframeTypes; airframeTypes << "Fixed Wing" << "Multirotor" << "Helicopter" << "Ground" << "Custom"; m_aircraft->aircraftType->addItems(airframeTypes); - m_aircraft->aircraftType->setCurrentIndex(1); //Set default vehicle to MultiRotor - m_aircraft->airframesWidget->setCurrentIndex(1); // Force the tab index to match - QStringList fixedWingTypes; - fixedWingTypes << "Elevator aileron rudder" << "Elevon" << "Vtail"; - m_aircraft->fixedWingType->addItems(fixedWingTypes); - m_aircraft->fixedWingType->setCurrentIndex(0); //Set default model to "Elevator aileron rudder" + // Set default vehicle to MultiRotor + //m_aircraft->aircraftType->setCurrentIndex(3); - QStringList groundVehicleTypes; - groundVehicleTypes << "Turnable (car)" << "Differential (tank)" << "Motorcycle"; - m_aircraft->groundVehicleType->addItems(groundVehicleTypes); - m_aircraft->groundVehicleType->setCurrentIndex(0); //Set default model to "Turnable (car)" - - QStringList multiRotorTypes; - multiRotorTypes << "Tricopter Y"<< "Quad +" << "Quad X" << - "Hexacopter" << "Hexacopter X" << "Hexacopter Y6" << - "Octocopter" << "Octocopter V" << "Octo Coax +" << "Octo Coax X" ; - m_aircraft->multirotorFrameType->addItems(multiRotorTypes); - m_aircraft->multirotorFrameType->setCurrentIndex(2); //Set default model to "Quad X" - - - //NEW STYLE: Loop through the widgets looking for all widgets that have "ChannelBox" in their name - // The upshot of this is that ALL new ComboBox widgets for selecting the output channel must have "ChannelBox" in their name - foreach(QComboBox *combobox, this->findChildren(QRegExp("\\S+ChannelBo\\S+")))//FOR WHATEVER REASON, THIS DOES NOT WORK WITH ChannelBox. ChannelBo is sufficiently accurate - { - combobox->addItems(channelNames); - } - - // Setup the Multirotor picture in the Quad settings interface - m_aircraft->quadShape->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_aircraft->quadShape->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - QSvgRenderer *renderer = new QSvgRenderer(); - renderer->load(QString(":/configgadget/images/multirotor-shapes.svg")); - quad = new QGraphicsSvgItem(); - quad->setSharedRenderer(renderer); - quad->setElementId("quad-x"); - QGraphicsScene *scene = new QGraphicsScene(this); - scene->addItem(quad); - scene->setSceneRect(quad->boundingRect()); - m_aircraft->quadShape->setScene(scene); - - // Put combo boxes in line one of the custom mixer table: - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - UAVObjectField* field = obj->getField(QString("Mixer1Type")); - QStringList list = field->getOptions(); - for (int i=0; i<(int)(VehicleConfig::CHANNEL_NUMELEM); i++) { - QComboBox* qb = new QComboBox(m_aircraft->customMixerTable); - qb->addItems(list); - m_aircraft->customMixerTable->setCellWidget(0,i,qb); - } - - SpinBoxDelegate *sbd = new SpinBoxDelegate(); - for (int i=1; i<(int)(VehicleConfig::CHANNEL_NUMELEM); i++) { - m_aircraft->customMixerTable->setItemDelegateForRow(i, sbd); - } - - // create and setup a MultiRotor config widget - m_multirotor = new ConfigMultiRotorWidget(m_aircraft); - m_multirotor->quad = quad; - m_multirotor->uiowner = this; - m_multirotor->setupUI(m_aircraft->multirotorFrameType->currentText()); - - // create and setup a GroundVehicle config widget - m_groundvehicle = new ConfigGroundVehicleWidget(m_aircraft); - m_groundvehicle->setupUI(m_aircraft->groundVehicleType->currentText() ); - - // create and setup a FixedWing config widget - m_fixedwing = new ConfigFixedWingWidget(m_aircraft); - m_fixedwing->setupUI(m_aircraft->fixedWingType->currentText() ); - - // create and setup a Helicopter config widget - m_heli = m_aircraft->widget_3; - m_heli->setupUI(QString("HeliCP")); - - //Connect aircraft type selection dropbox to callback function + // Connect aircraft type selection dropbox to callback function connect(m_aircraft->aircraftType, SIGNAL(currentIndexChanged(int)), this, SLOT(switchAirframeType(int))); - //Connect airframe selection dropbox to callback functions - connect(m_aircraft->fixedWingType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString))); - connect(m_aircraft->multirotorFrameType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString))); - connect(m_aircraft->groundVehicleType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString))); - //mdl connect(m_heli->m_ccpm->ccpmType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString))); - - //Connect the three feed forward test checkboxes + // Connect the three feed forward test checkboxes connect(m_aircraft->ffTestBox1, SIGNAL(clicked(bool)), this, SLOT(enableFFTest())); connect(m_aircraft->ffTestBox2, SIGNAL(clicked(bool)), this, SLOT(enableFFTest())); connect(m_aircraft->ffTestBox3, SIGNAL(clicked(bool)), this, SLOT(enableFFTest())); - //Connect the multirotor motor reverse checkbox - connect(m_aircraft->MultirotorRevMixercheckBox, SIGNAL(clicked(bool)), this, SLOT(reverseMultirotorMotor())); - // Connect the help pushbutton connect(m_aircraft->airframeHelp, SIGNAL(clicked()), this, SLOT(openHelp())); + enableControls(false); + refreshWidgetsValues(); - addToDirtyMonitor(); + + // register widgets for dirty state management + addWidget(m_aircraft->aircraftType); + + // register FF widgets for dirty state management + addWidget(m_aircraft->feedForwardSlider); + addWidget(m_aircraft->accelTime); + addWidget(m_aircraft->decelTime); + addWidget(m_aircraft->maxAccelSlider); disableMouseWheelEvents(); - m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); } - /** Destructor */ @@ -237,174 +162,159 @@ ConfigVehicleTypeWidget::~ConfigVehicleTypeWidget() // Do nothing } -/** - Static function to get currently assigned channelDescriptions - for all known vehicle types; instantiates the appropriate object - then asks it to supply channel descs - */ -QStringList ConfigVehicleTypeWidget::getChannelDescriptions() -{ - int i; - QStringList channelDesc; - - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - UAVObjectManager * objMngr = pm->getObject(); - Q_ASSERT(objMngr); - - // get an instance of systemsettings - SystemSettings * systemSettings = SystemSettings::GetInstance(objMngr); - Q_ASSERT(systemSettings); - SystemSettings::DataFields systemSettingsData = systemSettings->getData(); - - switch (systemSettingsData.AirframeType) - { - // fixed wing - case SystemSettings::AIRFRAMETYPE_FIXEDWING: - case SystemSettings::AIRFRAMETYPE_FIXEDWINGELEVON: - case SystemSettings::AIRFRAMETYPE_FIXEDWINGVTAIL: - { - channelDesc = ConfigFixedWingWidget::getChannelDescriptions(); - } - break; - - // helicp - case SystemSettings::AIRFRAMETYPE_HELICP: - { - channelDesc = ConfigCcpmWidget::getChannelDescriptions(); - } - break; - - //multirotor - case SystemSettings::AIRFRAMETYPE_VTOL: - case SystemSettings::AIRFRAMETYPE_TRI: - case SystemSettings::AIRFRAMETYPE_QUADX: - case SystemSettings::AIRFRAMETYPE_QUADP: - case SystemSettings::AIRFRAMETYPE_OCTOV: - case SystemSettings::AIRFRAMETYPE_OCTOCOAXX: - case SystemSettings::AIRFRAMETYPE_OCTOCOAXP: - case SystemSettings::AIRFRAMETYPE_OCTO: - case SystemSettings::AIRFRAMETYPE_HEXAX: - case SystemSettings::AIRFRAMETYPE_HEXACOAX: - case SystemSettings::AIRFRAMETYPE_HEXA: - { - channelDesc = ConfigMultiRotorWidget::getChannelDescriptions(); - } - break; - - // ground - case SystemSettings::AIRFRAMETYPE_GROUNDVEHICLECAR: - case SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEDIFFERENTIAL: - case SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEMOTORCYCLE: - { - channelDesc = ConfigGroundVehicleWidget::getChannelDescriptions(); - } - break; - - default: - { - for (i=0; i < (int)(VehicleConfig::CHANNEL_NUMELEM); i++) - channelDesc.append(QString("-")); - } - break; - } - -// for (i=0; i < channelDesc.count(); i++) -// qDebug() << QString("Channel %0 = %1").arg(i).arg(channelDesc[i]); - - return channelDesc; -} - - -/** - Slot for switching the airframe type. We do it explicitely - rather than a signal in the UI, because we want to force a fitInView of the quad shapes. - This is because this method (fitinview) only works when the widget is shown. - */ void ConfigVehicleTypeWidget::switchAirframeType(int index) { - m_aircraft->airframesWidget->setCurrentIndex(index); - m_aircraft->quadShape->setSceneRect(quad->boundingRect()); - m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); - if (m_aircraft->aircraftType->findText("Custom")) { - m_aircraft->customMixerTable->resizeColumnsToContents(); - for (int i=0;i<(int)(VehicleConfig::CHANNEL_NUMELEM);i++) { - m_aircraft->customMixerTable->setColumnWidth(i,(m_aircraft->customMixerTable->width()- - m_aircraft->customMixerTable->verticalHeader()->width())/10); - } - } -} - - -/** - WHAT DOES THIS DO??? - */ -void ConfigVehicleTypeWidget::showEvent(QShowEvent *event) -{ - Q_UNUSED(event) - // Thit fitInView method should only be called now, once the - // widget is shown, otherwise it cannot compute its values and - // the result is usually a ahrsbargraph that is way too small. - m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); - m_aircraft->customMixerTable->resizeColumnsToContents(); - for (int i=0;i<(int)(VehicleConfig::CHANNEL_NUMELEM);i++) { - m_aircraft->customMixerTable->setColumnWidth(i,(m_aircraft->customMixerTable->width()- - m_aircraft->customMixerTable->verticalHeader()->width())/ 10); - } + // TODO not safe w/r to translation!!! + QString frameCategory = m_aircraft->aircraftType->currentText(); + m_aircraft->airframesWidget->setCurrentWidget(getVehicleConfigWidget(frameCategory)); } /** - Resize the GUI contents when the user changes the window size - */ -void ConfigVehicleTypeWidget::resizeEvent(QResizeEvent* event) + Refreshes the current value of the SystemSettings which holds the aircraft type + Note: The default behavior of ConfigTaskWidget is bypassed. + Therefore no automatic synchronization of UAV Objects to UI is done. + */ +void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *o) { - Q_UNUSED(event); - m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); - // Make the custom table columns autostretch: - m_aircraft->customMixerTable->resizeColumnsToContents(); - for (int i=0;i<(int)(VehicleConfig::CHANNEL_NUMELEM);i++) { - m_aircraft->customMixerTable->setColumnWidth(i,(m_aircraft->customMixerTable->width()- - m_aircraft->customMixerTable->verticalHeader()->width())/ 10); - } + Q_UNUSED(o); + if (!allObjectsUpdated()) { + return; + } + + bool dirty = isDirty(); + + // Get the Airframe type from the system settings: + UAVDataObject *system = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings"))); + Q_ASSERT(system); + + UAVObjectField *field = system->getField(QString("AirframeType")); + Q_ASSERT(field); + + // At this stage, we will need to have some hardcoded settings in this code, this + // is not ideal, but there you go. + QString frameType = field->getValue().toString(); + qDebug() << "ConfigVehicleTypeWidget::refreshWidgetsValues - frame type:" << frameType; + + QString category = frameCategory(frameType); + setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText(category)); + + VehicleConfig *vehicleConfig = getVehicleConfigWidget(category); + if (vehicleConfig) { + vehicleConfig->refreshWidgetsValues(frameType); + } + + updateFeedForwardUI(); + + setDirty(dirty); + + qDebug() << "ConfigVehicleTypeWidget::refreshWidgetsValues - end"; } +/** + Sends the config to the board (airframe type) -void ConfigVehicleTypeWidget::toggleAileron2(int index) + We do all the tasks common to all airframes, or family of airframes, and + we call additional methods for specific frames, so that we do not have a code + that is too heavy. + + Note: The default behavior of ConfigTaskWidget is bypassed. + Therefore no automatic synchronization of UI to UAV Objects is done. +*/ +void ConfigVehicleTypeWidget::updateObjectsFromWidgets() { - if (index) { - m_aircraft->fwAileron2ChannelBox->setEnabled(true); - m_aircraft->fwAileron2Label->setEnabled(true); + // Airframe type defaults to Custom + QString airframeType = "Custom"; + + VehicleConfig *vehicleConfig = (VehicleConfig *) m_aircraft->airframesWidget->currentWidget(); + if (vehicleConfig) { + airframeType = vehicleConfig->updateConfigObjectsFromWidgets(); + } + + // set the airframe type + UAVDataObject *system = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings"))); + Q_ASSERT(system); + + QPointer field = system->getField(QString("AirframeType")); + if (field) { + field->setValue(airframeType); + } + + // Update feed forward settings + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); + Q_ASSERT(mixer); + + QPointer vconfig = new VehicleConfig(); + + vconfig->setMixerValue(mixer, "FeedForward", m_aircraft->feedForwardSlider->value() / 100.0); + vconfig->setMixerValue(mixer, "AccelTime", m_aircraft->accelTime->value()); + vconfig->setMixerValue(mixer, "DecelTime", m_aircraft->decelTime->value()); + vconfig->setMixerValue(mixer, "MaxAccel", m_aircraft->maxAccelSlider->value()); + + // TODO call refreshWidgetsValues() to reflect actual saved values ? + updateFeedForwardUI(); +} + +QString ConfigVehicleTypeWidget::frameCategory(QString frameType) +{ + QString category; + if (frameType == "FixedWing" || frameType == "Elevator aileron rudder" || frameType == "FixedWingElevon" + || frameType == "Elevon" || frameType == "FixedWingVtail" || frameType == "Vtail") { + category = "Fixed Wing"; + } else if (frameType == "Tri" || frameType == "Tricopter Y" || frameType == "QuadX" || frameType == "Quad X" + || frameType == "QuadP" || frameType == "Quad +" || frameType == "Hexa" || frameType == "Hexacopter" + || frameType == "HexaX" || frameType == "Hexacopter X" || frameType == "HexaCoax" + || frameType == "Hexacopter Y6" || frameType == "Octo" || frameType == "Octocopter" || frameType == "OctoV" + || frameType == "Octocopter V" || frameType == "OctoCoaxP" || frameType == "Octo Coax +" + || frameType == "OctoCoaxX" || frameType == "Octo Coax X") { + category = "Multirotor"; + } else if (frameType == "HeliCP") { + category = "Helicopter"; + } else if (frameType == "GroundVehicleCar" || frameType == "Turnable (car)" + || frameType == "GroundVehicleDifferential" || frameType == "Differential (tank)" + || frameType == "GroundVehicleMotorcyle" || frameType == "Motorcycle") { + category = "Ground"; } else { - m_aircraft->fwAileron2ChannelBox->setEnabled(false); - m_aircraft->fwAileron2Label->setEnabled(false); + category = "Custom"; } + return category; } -void ConfigVehicleTypeWidget::toggleElevator2(int index) +VehicleConfig *ConfigVehicleTypeWidget::getVehicleConfigWidget(QString frameCategory) { - if (index) { - m_aircraft->fwElevator2ChannelBox->setEnabled(true); - m_aircraft->fwElevator2Label->setEnabled(true); - } else { - m_aircraft->fwElevator2ChannelBox->setEnabled(false); - m_aircraft->fwElevator2Label->setEnabled(false); + VehicleConfig *vehiculeConfig; + if (!vehicleIndexMap.contains(frameCategory)) { + // create config widget + vehiculeConfig = createVehicleConfigWidget(frameCategory); + // bind config widget "field" to this ConfigTaskWodget + // this is necessary to get "dirty" state management + vehiculeConfig->registerWidgets(*this); + // add config widget to UI + int index = m_aircraft->airframesWidget->insertWidget(m_aircraft->airframesWidget->count(), vehiculeConfig); + vehicleIndexMap[frameCategory] = index; } + int index = vehicleIndexMap.value(frameCategory); + vehiculeConfig = (VehicleConfig *) m_aircraft->airframesWidget->widget(index); + return vehiculeConfig; } -void ConfigVehicleTypeWidget::toggleRudder2(int index) +VehicleConfig *ConfigVehicleTypeWidget::createVehicleConfigWidget(QString frameCategory) { - if (index) { - m_aircraft->fwRudder2ChannelBox->setEnabled(true); - m_aircraft->fwRudder2Label->setEnabled(true); - } else { - m_aircraft->fwRudder2ChannelBox->setEnabled(false); - m_aircraft->fwRudder2Label->setEnabled(false); + qDebug() << "ConfigVehicleTypeWidget::createVehicleConfigWidget - creating" << frameCategory; + if (frameCategory == "Fixed Wing") { + return new ConfigFixedWingWidget(); + } else if (frameCategory == "Multirotor") { + return new ConfigMultiRotorWidget(); + } else if (frameCategory == "Helicopter") { + return new ConfigCcpmWidget(); + } else if (frameCategory == "Ground") { + return new ConfigGroundVehicleWidget(); + } else if (frameCategory == "Custom") { + return new ConfigCustomWidget(); } + return NULL; } -///////////////////////////////////////////////////////// -/// Feed Forward Testing -///////////////////////////////////////////////////////// /** Enables and runs feed forward testing */ @@ -414,13 +324,12 @@ void ConfigVehicleTypeWidget::enableFFTest() // - Check if all three checkboxes are checked // - Every other timer event: toggle engine from 45% to 55% // - Every other time event: send FF settings to flight FW - if (m_aircraft->ffTestBox1->isChecked() && - m_aircraft->ffTestBox2->isChecked() && - m_aircraft->ffTestBox3->isChecked()) { - if (!ffTuningInProgress) - { + if (m_aircraft->ffTestBox1->isChecked() && m_aircraft->ffTestBox2->isChecked() + && m_aircraft->ffTestBox3->isChecked()) { + if (!ffTuningInProgress) { // Initiate tuning: - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ManualControlCommand"))); + UAVDataObject *obj = dynamic_cast(getObjectManager()->getObject( + QString("ManualControlCommand"))); UAVObject::Metadata mdata = obj->getMetadata(); accInitialData = mdata; UAVObject::SetFlightAccess(mdata, UAVObject::ACCESS_READONLY); @@ -440,9 +349,10 @@ void ConfigVehicleTypeWidget::enableFFTest() vconfig->setMixerValue(mixer, "DecelTime", m_aircraft->decelTime->value()); vconfig->setMixerValue(mixer, "MaxAccel", m_aircraft->maxAccelSlider->value()); mixer->updated(); - } else { + } else { // Toggle motor state - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ManualControlCommand"))); + UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject( + QString("ManualControlCommand"))); double value = obj->getField("Throttle")->getDouble(); double target = (value < 0.5) ? 0.55 : 0.45; obj->getField("Throttle")->setValue(target); @@ -456,7 +366,8 @@ void ConfigVehicleTypeWidget::enableFFTest() // Disarm! if (ffTuningInProgress) { ffTuningInProgress = false; - UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ManualControlCommand"))); + UAVDataObject *obj = dynamic_cast(getObjectManager()->getObject( + QString("ManualControlCommand"))); UAVObject::Metadata mdata = obj->getMetadata(); mdata = accInitialData; // Restore metadata obj->setMetadata(mdata); @@ -464,310 +375,23 @@ void ConfigVehicleTypeWidget::enableFFTest() } } -/************************** - * Aircraft settings - **************************/ -/** - Refreshes the current value of the SystemSettings which holds the aircraft type - */ -void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject * o) -{ - Q_UNUSED(o); - - if(!allObjectsUpdated()) - return; - - bool dirty=isDirty(); - - // Get the Airframe type from the system settings: - UAVDataObject* system = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings"))); - Q_ASSERT(system); - - UAVObjectField *field = system->getField(QString("AirframeType")); - Q_ASSERT(field); - // At this stage, we will need to have some hardcoded settings in this code, this - // is not ideal, but there you go. - QString frameType = field->getValue().toString(); - setupAirframeUI(frameType); - - UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(mixer); - - QPointer vconfig = new VehicleConfig(); - - QList curveValues; - vconfig->getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, &curveValues); - - // is at least one of the curve values != 0? - if (vconfig->isValidThrottleCurve(&curveValues)) { - // yes, use the curve we just read from mixersettings - m_aircraft->multiThrottleCurve->initCurve(&curveValues); - m_aircraft->fixedWingThrottle->initCurve(&curveValues); - m_aircraft->groundVehicleThrottle1->initCurve(&curveValues); - } - else { - // no, init a straight curve - m_aircraft->multiThrottleCurve->initLinearCurve(curveValues.count(), 0.9); - m_aircraft->fixedWingThrottle->initLinearCurve(curveValues.count(), 1.0); - m_aircraft->groundVehicleThrottle1->initLinearCurve(curveValues.count(), 1.0); - } - - // Setup all Throttle2 curves for all types of airframes //AT THIS MOMENT, THAT MEANS ONLY GROUND VEHICLES - vconfig->getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, &curveValues); - - if (vconfig->isValidThrottleCurve(&curveValues)) { - m_aircraft->groundVehicleThrottle2->initCurve(&curveValues); - } - else { - m_aircraft->groundVehicleThrottle2->initLinearCurve(curveValues.count(), 1.0); - } - - // Load the Settings for fixed wing frames: - if (frameType.startsWith("FixedWing")) { - - // Retrieve fixed wing settings - m_fixedwing->refreshWidgetsValues(frameType); - - } else if (frameType == "Tri" || - frameType == "QuadX" || frameType == "QuadP" || - frameType == "Hexa" || frameType == "HexaCoax" || frameType == "HexaX" || - frameType == "Octo" || frameType == "OctoV" || frameType == "OctoCoaxP" || frameType == "OctoCoaxX" ) { - - // Retrieve multirotor settings - m_multirotor->refreshWidgetsValues(frameType); - } else if (frameType == "HeliCP") { - setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Helicopter")); - m_heli->refreshWidgetsValues(frameType); - - } else if (frameType.startsWith("GroundVehicle")) { - - // Retrieve ground vehicle settings - m_groundvehicle->refreshWidgetsValues(frameType); - - } else if (frameType == "Custom") { - setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Custom")); - } - - updateCustomAirframeUI(); - setDirty(dirty); -} - -/** - \brief Sets up the mixer depending on Airframe type. Accepts either system settings or - combo box entry from airframe type, as those do not overlap. - */ -void ConfigVehicleTypeWidget::setupAirframeUI(QString frameType) -{ - bool dirty=isDirty(); - if(frameType == "FixedWing" || frameType == "Elevator aileron rudder" || - frameType == "FixedWingElevon" || frameType == "Elevon" || - frameType == "FixedWingVtail" || frameType == "Vtail"){ - m_fixedwing->setupUI(frameType); - } - else if (frameType == "Tri" || frameType == "Tricopter Y" || - frameType == "QuadX" || frameType == "Quad X" || - frameType == "QuadP" || frameType == "Quad +" || - frameType == "Hexa" || frameType == "Hexacopter" || - frameType == "HexaX" || frameType == "Hexacopter X" || - frameType == "HexaCoax" || frameType == "Hexacopter Y6" || - frameType == "Octo" || frameType == "Octocopter" || - frameType == "OctoV" || frameType == "Octocopter V" || - frameType == "OctoCoaxP" || frameType == "Octo Coax +" || - frameType == "OctoCoaxX" || frameType == "Octo Coax X" ) { - - //Call multi-rotor setup UI - m_multirotor->setupUI(frameType); - } - else if (frameType == "HeliCP") { - m_heli->setupUI(frameType); - } - else if (frameType == "GroundVehicleCar" || frameType == "Turnable (car)" || - frameType == "GroundVehicleDifferential" || frameType == "Differential (tank)" || - frameType == "GroundVehicleMotorcyle" || frameType == "Motorcycle") { - m_groundvehicle->setupUI(frameType); - } - - //SHOULDN'T THIS BE DONE ONLY IN QUAD SETUP, AND NOT ALL THE REST??? - m_aircraft->quadShape->setSceneRect(quad->boundingRect()); - m_aircraft->quadShape->fitInView(quad, Qt::KeepAspectRatio); - - setDirty(dirty); -} - - -/** - Reset the contents of a field - */ -void ConfigVehicleTypeWidget::resetField(UAVObjectField * field) -{ - for (unsigned int i=0;igetNumElements();i++) { - field->setValue(0,i); - } -} - /** Updates the custom airframe settings based on the current airframe. Note: does NOT ask for an object refresh itself! */ -void ConfigVehicleTypeWidget::updateCustomAirframeUI() -{ - UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); - Q_ASSERT(mixer); - - QPointer vconfig = new VehicleConfig(); - - QList curveValues; - vconfig->getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, &curveValues); - - // is at least one of the curve values != 0? - if (vconfig->isValidThrottleCurve(&curveValues)) { - m_aircraft->customThrottle1Curve->initCurve(&curveValues); - } - else { - // no, init a straight curve - m_aircraft->customThrottle1Curve->initLinearCurve(curveValues.count(), 1.0); - } - - if (MixerSettings* mxr = qobject_cast(mixer)) { - MixerSettings::DataFields mixerSettingsData = mxr->getData(); - if (mixerSettingsData.Curve2Source == MixerSettings::CURVE2SOURCE_THROTTLE) - m_aircraft->customThrottle2Curve->setMixerType(MixerCurve::MIXERCURVE_THROTTLE); - else { - m_aircraft->customThrottle2Curve->setMixerType(MixerCurve::MIXERCURVE_PITCH); - } - } - - // Setup all Throttle2 curves for all types of airframes - vconfig->getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, &curveValues); - - if (vconfig->isValidThrottleCurve(&curveValues)) { - m_aircraft->customThrottle2Curve->initCurve(&curveValues); - } - else { - m_aircraft->customThrottle2Curve->initLinearCurve(curveValues.count(), 1.0, m_aircraft->customThrottle2Curve->getMin()); - } - - // Update the mixer table: - for (int channel=0; channel < m_aircraft->customMixerTable->columnCount(); channel++) { - UAVObjectField* field = mixer->getField(mixerTypes.at(channel)); - if (field) - { - QComboBox* q = (QComboBox*)m_aircraft->customMixerTable->cellWidget(0,channel); - if (q) - { - QString s = field->getValue().toString(); - setComboCurrentIndex(q, q->findText(s)); - } - - m_aircraft->customMixerTable->item(1,channel)->setText( - QString::number(vconfig->getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1))); - m_aircraft->customMixerTable->item(2,channel)->setText( - QString::number(vconfig->getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE2))); - m_aircraft->customMixerTable->item(3,channel)->setText( - QString::number(vconfig->getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_ROLL))); - m_aircraft->customMixerTable->item(4,channel)->setText( - QString::number(vconfig->getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_PITCH))); - m_aircraft->customMixerTable->item(5,channel)->setText( - QString::number(vconfig->getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_YAW))); - } - } - - // Update feed forward settings - m_aircraft->feedForwardSlider->setValue(vconfig->getMixerValue(mixer,"FeedForward") * 100); - m_aircraft->accelTime->setValue(vconfig->getMixerValue(mixer,"AccelTime")); - m_aircraft->decelTime->setValue(vconfig->getMixerValue(mixer,"DecelTime")); - m_aircraft->maxAccelSlider->setValue(vconfig->getMixerValue(mixer,"MaxAccel")); -} - - -/** - Sends the config to the board (airframe type) - - We do all the tasks common to all airframes, or family of airframes, and - we call additional methods for specific frames, so that we do not have a code - that is too heavy. -*/ -void ConfigVehicleTypeWidget::updateObjectsFromWidgets() +void ConfigVehicleTypeWidget::updateFeedForwardUI() { - UAVDataObject* mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); + UAVDataObject *mixer = dynamic_cast(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(mixer); QPointer vconfig = new VehicleConfig(); // Update feed forward settings - vconfig->setMixerValue(mixer, "FeedForward", m_aircraft->feedForwardSlider->value() / 100.0); - vconfig->setMixerValue(mixer, "AccelTime", m_aircraft->accelTime->value()); - vconfig->setMixerValue(mixer, "DecelTime", m_aircraft->decelTime->value()); - vconfig->setMixerValue(mixer, "MaxAccel", m_aircraft->maxAccelSlider->value()); - - QString airframeType = "Custom"; //Sets airframe type default to "Custom" - if (m_aircraft->aircraftType->currentText() == "Fixed Wing") { - airframeType = m_fixedwing->updateConfigObjectsFromWidgets(); - } - else if (m_aircraft->aircraftType->currentText() == "Multirotor") { - airframeType = m_multirotor->updateConfigObjectsFromWidgets(); - } - else if (m_aircraft->aircraftType->currentText() == "Helicopter") { - airframeType = m_heli->updateConfigObjectsFromWidgets(); - } - else if (m_aircraft->aircraftType->currentText() == "Ground") { - airframeType = m_groundvehicle->updateConfigObjectsFromWidgets(); - } - else { - vconfig->setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->customThrottle1Curve->getCurve()); - vconfig->setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, m_aircraft->customThrottle2Curve->getCurve()); - - // Update the table: - for (int channel=0; channel<(int)(VehicleConfig::CHANNEL_NUMELEM); channel++) { - QComboBox* q = (QComboBox*)m_aircraft->customMixerTable->cellWidget(0,channel); - if(q->currentText()=="Disabled") - vconfig->setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED); - else if(q->currentText()=="Motor") - vconfig->setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_MOTOR); - else if(q->currentText()=="Servo") - vconfig->setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_SERVO); - else if(q->currentText()=="CameraRoll") - vconfig->setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_CAMERAROLL); - else if(q->currentText()=="CameraPitch") - vconfig->setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_CAMERAPITCH); - else if(q->currentText()=="CameraYaw") - vconfig->setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_CAMERAYAW); - else if(q->currentText()=="Accessory0") - vconfig->setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_ACCESSORY0); - else if(q->currentText()=="Accessory1") - vconfig->setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_ACCESSORY1); - else if(q->currentText()=="Accessory2") - vconfig->setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_ACCESSORY2); - else if(q->currentText()=="Accessory3") - vconfig->setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_ACCESSORY3); - else if(q->currentText()=="Accessory4") - vconfig->setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_ACCESSORY4); - else if(q->currentText()=="Accessory5") - vconfig->setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_ACCESSORY5); - - vconfig->setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1, - m_aircraft->customMixerTable->item(1,channel)->text().toDouble()); - vconfig->setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE2, - m_aircraft->customMixerTable->item(2,channel)->text().toDouble()); - vconfig->setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_ROLL, - m_aircraft->customMixerTable->item(3,channel)->text().toDouble()); - vconfig->setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_PITCH, - m_aircraft->customMixerTable->item(4,channel)->text().toDouble()); - vconfig->setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_YAW, - m_aircraft->customMixerTable->item(5,channel)->text().toDouble()); - } - } - - // set the airframe type - UAVDataObject* system = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings"))); - Q_ASSERT(system); - - QPointer field = system->getField(QString("AirframeType")); - if (field) - field->setValue(airframeType); - - updateCustomAirframeUI(); + m_aircraft->feedForwardSlider->setValue(vconfig->getMixerValue(mixer, "FeedForward") * 100); + m_aircraft->accelTime->setValue(vconfig->getMixerValue(mixer, "AccelTime")); + m_aircraft->decelTime->setValue(vconfig->getMixerValue(mixer, "DecelTime")); + m_aircraft->maxAccelSlider->setValue(vconfig->getMixerValue(mixer, "MaxAccel")); } /** @@ -775,7 +399,6 @@ void ConfigVehicleTypeWidget::updateObjectsFromWidgets() */ void ConfigVehicleTypeWidget::openHelp() { - QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/x/44Cf", QUrl::StrictMode) ); } @@ -786,88 +409,7 @@ void ConfigVehicleTypeWidget::openHelp() */ void ConfigVehicleTypeWidget::setComboCurrentIndex(QComboBox* box, int index) { - if (index >= 0 && index < box->count()) + if (index >= 0 && index < box->count()) { box->setCurrentIndex(index); + } } - -void ConfigVehicleTypeWidget::reverseMultirotorMotor(){ - QString frameType = m_aircraft->multirotorFrameType->currentText(); - m_multirotor->drawAirframe(frameType); -} - - -/** - WHAT DOES THIS DO??? - */ -void ConfigVehicleTypeWidget::addToDirtyMonitor() -{ - addWidget(m_aircraft->customMixerTable); - addWidget(m_aircraft->customThrottle1Curve->getCurveWidget()); - addWidget(m_aircraft->customThrottle2Curve->getCurveWidget()); - addWidget(m_aircraft->multiThrottleCurve->getCurveWidget()); - addWidget(m_aircraft->fixedWingThrottle->getCurveWidget()); - addWidget(m_aircraft->fixedWingType); - addWidget(m_aircraft->groundVehicleThrottle1->getCurveWidget()); - addWidget(m_aircraft->groundVehicleThrottle2->getCurveWidget()); - addWidget(m_aircraft->groundVehicleType); - addWidget(m_aircraft->feedForwardSlider); - addWidget(m_aircraft->accelTime); - addWidget(m_aircraft->decelTime); - addWidget(m_aircraft->maxAccelSlider); - addWidget(m_aircraft->multirotorFrameType); - addWidget(m_aircraft->multiMotorChannelBox1); - addWidget(m_aircraft->multiMotorChannelBox2); - addWidget(m_aircraft->multiMotorChannelBox3); - addWidget(m_aircraft->multiMotorChannelBox4); - addWidget(m_aircraft->multiMotorChannelBox5); - addWidget(m_aircraft->multiMotorChannelBox6); - addWidget(m_aircraft->multiMotorChannelBox7); - addWidget(m_aircraft->multiMotorChannelBox8); - addWidget(m_aircraft->mrPitchMixLevel); - addWidget(m_aircraft->mrRollMixLevel); - addWidget(m_aircraft->mrYawMixLevel); - addWidget(m_aircraft->triYawChannelBox); - addWidget(m_aircraft->aircraftType); - addWidget(m_aircraft->fwEngineChannelBox); - addWidget(m_aircraft->fwAileron1ChannelBox); - addWidget(m_aircraft->fwAileron2ChannelBox); - addWidget(m_aircraft->fwElevator1ChannelBox); - addWidget(m_aircraft->fwElevator2ChannelBox); - addWidget(m_aircraft->fwRudder1ChannelBox); - addWidget(m_aircraft->fwRudder2ChannelBox); - addWidget(m_aircraft->elevonSlider1); - addWidget(m_aircraft->elevonSlider2); - addWidget(m_heli->m_ccpm->ccpmType); - addWidget(m_heli->m_ccpm->ccpmTailChannel); - addWidget(m_heli->m_ccpm->ccpmEngineChannel); - addWidget(m_heli->m_ccpm->ccpmServoWChannel); - addWidget(m_heli->m_ccpm->ccpmServoXChannel); - addWidget(m_heli->m_ccpm->ccpmServoYChannel); - addWidget(m_heli->m_ccpm->ccpmSingleServo); - addWidget(m_heli->m_ccpm->ccpmServoZChannel); - addWidget(m_heli->m_ccpm->ccpmAngleW); - addWidget(m_heli->m_ccpm->ccpmAngleX); - addWidget(m_heli->m_ccpm->ccpmCorrectionAngle); - addWidget(m_heli->m_ccpm->ccpmAngleZ); - addWidget(m_heli->m_ccpm->ccpmAngleY); - addWidget(m_heli->m_ccpm->ccpmCollectivePassthrough); - addWidget(m_heli->m_ccpm->ccpmLinkRoll); - addWidget(m_heli->m_ccpm->ccpmLinkCyclic); - addWidget(m_heli->m_ccpm->ccpmRevoSlider); - addWidget(m_heli->m_ccpm->ccpmREVOspinBox); - addWidget(m_heli->m_ccpm->ccpmCollectiveSlider); - addWidget(m_heli->m_ccpm->ccpmCollectivespinBox); - addWidget(m_heli->m_ccpm->ccpmCollectiveScale); - addWidget(m_heli->m_ccpm->ccpmCollectiveScaleBox); - addWidget(m_heli->m_ccpm->ccpmCyclicScale); - addWidget(m_heli->m_ccpm->ccpmPitchScale); - addWidget(m_heli->m_ccpm->ccpmPitchScaleBox); - addWidget(m_heli->m_ccpm->ccpmRollScale); - addWidget(m_heli->m_ccpm->ccpmRollScaleBox); - addWidget(m_heli->m_ccpm->SwashLvlPositionSlider); - addWidget(m_heli->m_ccpm->SwashLvlPositionSpinBox); - addWidget(m_heli->m_ccpm->ThrottleCurve->getCurveWidget()); - addWidget(m_heli->m_ccpm->PitchCurve->getCurveWidget()); - addWidget(m_heli->m_ccpm->ccpmAdvancedSettingsTable); -} - diff --git a/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.h b/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.h index e4cea4cc2..6184fd6fb 100644 --- a/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.h +++ b/ground/openpilotgcs/src/plugins/config/configvehicletypewidget.h @@ -28,98 +28,69 @@ #define CONFIGVEHICLETYPEWIDGET_H #include "ui_airframe.h" -#include "../uavobjectwidgetutils/configtaskwidget.h" -#include "extensionsystem/pluginmanager.h" -#include "uavobjectmanager.h" -#include "uavobject.h" -#include "uavtalk/telemetrymanager.h" - -#include "cfg_vehicletypes/configccpmwidget.h" -#include "cfg_vehicletypes/configfixedwingwidget.h" -#include "cfg_vehicletypes/configmultirotorwidget.h" -#include "cfg_vehicletypes/configgroundvehiclewidget.h" #include "cfg_vehicletypes/vehicleconfig.h" +#include "uavobject.h" +#include "../uavobjectwidgetutils/configtaskwidget.h" -#include -#include -#include - -class Ui_Widget; +#include +#include +#include +#include +#include +/* + * This class derives from ConfigTaskWidget and overrides its default "binding" mechanism. + * This widget bypasses automatic synchronization of UAVObjects and UI by providing its own implementations of + * virtual void refreshWidgetsValues(UAVObject *obj = NULL); + * virtual void updateObjectsFromWidgets(); + * + * It does use the "dirty" state management and registers its relevant widgets with ConfigTaskWidget to do so. + * + * This class also manages child ConfigTaskWidget : see VehicleConfig class and its derived classes. + * Note: for "dirty" state management it is important to register the fields of child widgets with the parent + * ConfigVehicleTypeWidget class. + * + * TODO consider to call "super" to benefit from default logic... + * TODO improve handling of relationship with VehicleConfig derived classes (i.e. ConfigTaskWidget within ConfigTaskWidget) + */ class ConfigVehicleTypeWidget: public ConfigTaskWidget { Q_OBJECT public: + static QStringList getChannelDescriptions(); + static void setComboCurrentIndex(QComboBox *box, int index); + ConfigVehicleTypeWidget(QWidget *parent = 0); ~ConfigVehicleTypeWidget(); - static QStringList getChannelDescriptions(); +protected slots: + virtual void refreshWidgetsValues(UAVObject *o = NULL); + virtual void updateObjectsFromWidgets(); private: Ui_AircraftWidget *m_aircraft; - ConfigCcpmWidget *m_heli; - ConfigFixedWingWidget *m_fixedwing; - ConfigMultiRotorWidget *m_multirotor; - ConfigGroundVehicleWidget *m_groundvehicle; + // Maps a frame category to its index in the m_aircraft->airframesWidget QStackedWidget + QMap vehicleIndexMap; - void updateCustomAirframeUI(); - void addToDirtyMonitor(); - void resetField(UAVObjectField * field); + QString frameCategory(QString frameType); - //void setMixerChannel(int channelNumber, bool channelIsMotor, QList vector); + VehicleConfig *getVehicleConfigWidget(QString frameCategory); + VehicleConfig *createVehicleConfigWidget(QString frameCategory); - QStringList channelNames; - QStringList mixerTypes; - QStringList mixerVectors; + // Feed Forward + void updateFeedForwardUI(); - QGraphicsSvgItem *quad; bool ffTuningInProgress; bool ffTuningPhase; UAVObject::Metadata accInitialData; private slots: - - virtual void refreshWidgetsValues(UAVObject * o=NULL); - virtual void updateObjectsFromWidgets(); - - void setComboCurrentIndex(QComboBox* box, int index); - - void setupAirframeUI(QString type); - - void toggleAileron2(int index); - void toggleElevator2(int index); - void toggleRudder2(int index); void switchAirframeType(int index); - - void enableFFTest(); void openHelp(); - void reverseMultirotorMotor(); + void enableFFTest(); -protected: - void showEvent(QShowEvent *event); - void resizeEvent(QResizeEvent *event); - - -}; - -class SpinBoxDelegate : public QItemDelegate -{ - Q_OBJECT - -public: - SpinBoxDelegate(QObject *parent = 0); - - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, - const QModelIndex &index) const; - - void setEditorData(QWidget *editor, const QModelIndex &index) const; - void setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const; - - void updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, const QModelIndex &index) const; }; #endif // CONFIGVEHICLETYPEWIDGET_H diff --git a/ground/openpilotgcs/src/plugins/coreplugin/qml/AboutDialog.qml b/ground/openpilotgcs/src/plugins/coreplugin/qml/AboutDialog.qml index 1f2706079..98ccf4ef3 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/qml/AboutDialog.qml +++ b/ground/openpilotgcs/src/plugins/coreplugin/qml/AboutDialog.qml @@ -39,74 +39,74 @@ ****************************************************************************/ import QtQuick 1.1 + import QtWebKit 1.0 // This is a tabbed pane element. Add a nested Rectangle to add a tab. TabWidget { - // Define AuthorsModel as type - property AuthorsModel authors: AuthorsModel {} - - id: tabs - width: 640; height: 480 - // This tab is for the GCS version information - Rectangle { - property string title: "OpenPilot GCS" - anchors.fill: parent - color: "#e3e3e3" - - Rectangle { - anchors.fill: parent; anchors.margins: 20 - color: "#e3e3e3" - Image { - source: "../images/openpilot_logo_128.png" - x: 0; y: 0; z: 100 - fillMode: Image.PreserveAspectFit - } - Flickable { - anchors.fill: parent - anchors.centerIn: parent - Text { - id: versionLabel - x: 156; y: 0 - width: 430; height: 379 - horizontalAlignment: Qt.AlignLeft - font.pixelSize: 12 - wrapMode: Text.WordWrap - // @var version exposed in authorsdialog.cpp - text: version - } - } - } - } - - // This tab is for the authors/contributors/credits - Rectangle { - property string title: "Authors" - anchors.fill: parent; color: "#e3e3e3" - Rectangle { - anchors.fill: parent; anchors.margins: 20 - color: "#e3e3e3" - Text { - id: description - text: "

These people have been key contributors to the OpenPilot project. Without the work of the people in this list, OpenPilot would not be what it is today.

This list is sorted alphabetically by name

" - width: 600 - wrapMode: Text.WordWrap - - } - ListView { - id: authorsView - y: description.y + description.height + 20 - width: parent.width; height: parent.height - description.height - 20 - spacing: 3 - model: authors - delegate: Text { - text: name + // Define AuthorsModel as type + property AuthorsModel authors: AuthorsModel {} + + id: tabs + width: 640; height: 480 + // This tab is for the GCS version information + Rectangle { + property string title: "OpenPilot GCS" + anchors.fill: parent + color: "#e3e3e3" + + Rectangle { + anchors.fill: parent; anchors.margins: 20 + color: "#e3e3e3" + Image { + source: "../images/openpilot_logo_128.png" + x: 0; y: 0; z: 100 + fillMode: Image.PreserveAspectFit + } + Flickable { + anchors.fill: parent + anchors.centerIn: parent + Text { + id: versionLabel + x: 156; y: 0 + width: 430; height: 379 + horizontalAlignment: Qt.AlignLeft + font.pixelSize: 12 + wrapMode: Text.WordWrap + // @var version exposed in authorsdialog.cpp + text: version + } } - clip: true - } - ScrollDecorator { - flickableItem: authorsView } } - } + // This tab is for the authors/contributors/credits + Rectangle { + property string title: "Authors" + anchors.fill: parent; color: "#e3e3e3" + Rectangle { + anchors.fill: parent; anchors.margins: 20 + color: "#e3e3e3" + Text { + id: description + text: "

These people have been key contributors to the OpenPilot project. Without the work of the people in this list, OpenPilot would not be what it is today.

This list is sorted alphabetically by name

" + width: 600 + wrapMode: Text.WordWrap + + } + ListView { + id: authorsView + y: description.y + description.height + 20 + width: parent.width; height: parent.height - description.height - 20 + spacing: 3 + model: authors + delegate: Text { + text: name + } + clip: true + } + ScrollDecorator { + flickableItem: authorsView + } + } + } } diff --git a/ground/openpilotgcs/src/plugins/config/images/curve-bg.svg b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/images/curve-bg.svg similarity index 81% rename from ground/openpilotgcs/src/plugins/config/images/curve-bg.svg rename to ground/openpilotgcs/src/plugins/uavobjectwidgetutils/images/curve-bg.svg index d8194ec7a..492db9174 100644 --- a/ground/openpilotgcs/src/plugins/config/images/curve-bg.svg +++ b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/images/curve-bg.svg @@ -14,7 +14,7 @@ height="253" id="svg2" version="1.1" - inkscape:version="0.48.2 r9819" + inkscape:version="0.48.4 r9939" sodipodi:docname="curve-bg.svg"> @@ -55,15 +55,15 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1.9966906" - inkscape:cx="181.06787" + inkscape:cx="102.93859" inkscape:cy="89.329853" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" inkscape:window-width="1440" inkscape:window-height="878" - inkscape:window-x="1695" - inkscape:window-y="97" + inkscape:window-x="148" + inkscape:window-y="40" inkscape:window-maximized="0" /> @@ -101,49 +101,49 @@ + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:5.30000019;stroke-opacity:0.28888890000000000;stroke-dasharray:none;stroke-dashoffset:3.70000000000000020" /> + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:5.30000019;stroke-opacity:0.28888890000000000;stroke-dasharray:none;stroke-dashoffset:3.70000000000000020" /> + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:5.30000019;stroke-opacity:0.28888890000000000;stroke-dasharray:none;stroke-dashoffset:3.70000000000000020;marker-start:none" /> + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.28888890000000000;stroke-miterlimit:5.30000019;stroke-dasharray:none;stroke-dashoffset:3.70000000000000020" /> + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.28888890000000000;stroke-miterlimit:5.30000019;stroke-dasharray:none;stroke-dashoffset:3.70000000000000020" /> diff --git a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvewidget.cpp b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvewidget.cpp index 63e388a28..4c52d1afb 100644 --- a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvewidget.cpp +++ b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/mixercurvewidget.cpp @@ -64,7 +64,7 @@ MixerCurveWidget::MixerCurveWidget(QWidget *parent) : QGraphicsView(parent) QGraphicsScene *scene = new QGraphicsScene(this); QSvgRenderer *renderer = new QSvgRenderer(); plot = new QGraphicsSvgItem(); - renderer->load(QString(":/configgadget/images/curve-bg.svg")); + renderer->load(QString(":/uavobjectwidgetutils/images/curve-bg.svg")); plot->setSharedRenderer(renderer); //plot->setElementId("map"); scene->addItem(plot); diff --git a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/uavobjectwidgetutils.pro b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/uavobjectwidgetutils.pro index cedaed7c3..b75b019ce 100644 --- a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/uavobjectwidgetutils.pro +++ b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/uavobjectwidgetutils.pro @@ -2,16 +2,19 @@ TEMPLATE = lib TARGET = UAVObjectWidgetUtils DEFINES += UAVOBJECTWIDGETUTILS_LIBRARY QT += svg + include(../../openpilotgcsplugin.pri) include(uavobjectwidgetutils_dependencies.pri) + HEADERS += uavobjectwidgetutils_global.h \ uavobjectwidgetutilsplugin.h \ configtaskwidget.h \ mixercurvewidget.h \ mixercurvepoint.h \ mixercurveline.h \ - smartsavebutton.h \ + smartsavebutton.h \ popupwidget.h + SOURCES += uavobjectwidgetutilsplugin.cpp \ configtaskwidget.cpp \ mixercurvewidget.cpp \ @@ -20,6 +23,7 @@ SOURCES += uavobjectwidgetutilsplugin.cpp \ smartsavebutton.cpp \ popupwidget.cpp +RESOURCES += uavobjectwidgetutils.qrc OTHER_FILES += UAVObjectWidgetUtils.pluginspec diff --git a/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/uavobjectwidgetutils.qrc b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/uavobjectwidgetutils.qrc new file mode 100644 index 000000000..9cbc86131 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/uavobjectwidgetutils/uavobjectwidgetutils.qrc @@ -0,0 +1,5 @@ + + + images/curve-bg.svg + +