diff --git a/flight/Bootloaders/BootloaderUpdater/main.c b/flight/Bootloaders/BootloaderUpdater/main.c index b7348dac4..ff2c5ae2e 100644 --- a/flight/Bootloaders/BootloaderUpdater/main.c +++ b/flight/Bootloaders/BootloaderUpdater/main.c @@ -34,7 +34,7 @@ /* Prototype of PIOS_Board_Init() function */ extern void PIOS_Board_Init(void); extern void FLASH_Download(); -void error(int); +void error(int, int); /* The ADDRESSES of the _binary_* symbols are the important * data. This is non-intuitive for _binary_size where you @@ -47,7 +47,8 @@ const uint32_t * embedded_image_start = (uint32_t *) &(_binary_start); const uint32_t * embedded_image_end = (uint32_t *) &(_binary_end); const uint32_t embedded_image_size = (uint32_t) &(_binary_size); -int main() { +int main() +{ PIOS_SYS_Init(); PIOS_Board_Init(); @@ -58,7 +59,7 @@ int main() { /// Self overwrite check uint32_t base_address = SCB->VTOR; if ((0x08000000 + embedded_image_size) > base_address) - error(PIOS_LED_HEARTBEAT); + error(PIOS_LED_HEARTBEAT, 1); /// /* @@ -70,7 +71,7 @@ int main() { */ /* Calculate how far the board_info_blob is from the beginning of the bootloader */ - uint32_t board_info_blob_offset = (uint32_t)&pios_board_info_blob - (uint32_t)0x08000000; + uint32_t board_info_blob_offset = (uint32_t) &pios_board_info_blob - (uint32_t)0x08000000; /* Use the same offset into our embedded bootloader image */ struct pios_board_info * new_board_info_blob = (struct pios_board_info *) @@ -80,7 +81,7 @@ int main() { if ((pios_board_info_blob.magic != new_board_info_blob->magic) || (pios_board_info_blob.board_type != new_board_info_blob->board_type) || (pios_board_info_blob.board_rev != new_board_info_blob->board_rev)) { - error(PIOS_LED_HEARTBEAT); + error(PIOS_LED_HEARTBEAT, 2); } /* Embedded bootloader looks like it's the right one for this HW, proceed... */ @@ -108,30 +109,30 @@ int main() { } if (fail == true) - error(PIOS_LED_HEARTBEAT); + error(PIOS_LED_HEARTBEAT, 3); /// /// Bootloader programing - for (uint32_t offset = 0; offset < embedded_image_size/sizeof(uint32_t); ++offset) { + for (uint32_t offset = 0; offset < embedded_image_size / sizeof(uint32_t); ++offset) { bool result = false; PIOS_LED_Toggle(PIOS_LED_HEARTBEAT); for (uint8_t retry = 0; retry < MAX_WRI_RETRYS; ++retry) { if (result == false) { result = (FLASH_ProgramWord(0x08000000 + (offset * 4), embedded_image_start[offset]) - == FLASH_COMPLETE) ? true : false; + == FLASH_COMPLETE) ? true : false; } } if (result == false) - error(PIOS_LED_HEARTBEAT); + error(PIOS_LED_HEARTBEAT, 4); } /// for (uint8_t x = 0; x < 3; ++x) { - PIOS_LED_On(PIOS_LED_HEARTBEAT); - PIOS_DELAY_WaitmS(1000); - PIOS_LED_Off(PIOS_LED_HEARTBEAT); - PIOS_DELAY_WaitmS(1000); + PIOS_LED_On(PIOS_LED_HEARTBEAT); + PIOS_DELAY_WaitmS(1000); + PIOS_LED_Off(PIOS_LED_HEARTBEAT); + PIOS_DELAY_WaitmS(1000); } /// Invalidate the bootloader updater so we won't run @@ -145,11 +146,22 @@ int main() { } -void error(int led) { +void error(int led, int code) +{ for (;;) { - PIOS_LED_On(led); - PIOS_DELAY_WaitmS(500); - PIOS_LED_Off(led); - PIOS_DELAY_WaitmS(500); + PIOS_DELAY_WaitmS(1000); + for (int x = 0; x < code; x++) { + PIOS_LED_On(led); + PIOS_DELAY_WaitmS(200); + PIOS_LED_Off(led); + PIOS_DELAY_WaitmS(1000); + } + PIOS_DELAY_WaitmS(1000); + for (int x = 0; x < 10; x++) { + PIOS_LED_On(led); + PIOS_DELAY_WaitmS(200); + PIOS_LED_Off(led); + PIOS_DELAY_WaitmS(200); + } } -} +} \ No newline at end of file diff --git a/flight/CopterControl/Makefile b/flight/CopterControl/Makefile index 9b46bead1..dc20ea525 100644 --- a/flight/CopterControl/Makefile +++ b/flight/CopterControl/Makefile @@ -233,6 +233,7 @@ SRC += $(OPUAVSYNTHDIR)/ratedesired.c SRC += $(OPUAVSYNTHDIR)/baroaltitude.c SRC += $(OPUAVSYNTHDIR)/txpidsettings.c SRC += $(OPUAVSYNTHDIR)/airspeedactual.c +SRC += $(OPUAVSYNTHDIR)/mpu6000settings.c endif diff --git a/flight/CopterControl/System/pios_board.c b/flight/CopterControl/System/pios_board.c index 057767105..e3eb5826b 100644 --- a/flight/CopterControl/System/pios_board.c +++ b/flight/CopterControl/System/pios_board.c @@ -79,6 +79,7 @@ uint32_t pios_usb_rctx_id; */ #if defined(PIOS_INCLUDE_MPU6000) #include "pios_mpu6000.h" +#include "pios_mpu6000_config.h" static const struct pios_exti_cfg pios_exti_mpu6000_cfg __exti_config = { .vector = PIOS_MPU6000_IRQHandler, .line = EXTI_Line3, @@ -112,13 +113,15 @@ static const struct pios_mpu6000_cfg pios_mpu6000_cfg = { .exti_cfg = &pios_exti_mpu6000_cfg, .Fifo_store = PIOS_MPU6000_FIFO_TEMP_OUT | PIOS_MPU6000_FIFO_GYRO_X_OUT | PIOS_MPU6000_FIFO_GYRO_Y_OUT | PIOS_MPU6000_FIFO_GYRO_Z_OUT, // Clock at 8 khz, downsampled by 16 for 500 Hz - .Smpl_rate_div = 15, + .Smpl_rate_div_no_dlp = 15, + // Clock at 1 khz, downsampled by 2 for 500 Hz + .Smpl_rate_div_dlp = 1, .interrupt_cfg = PIOS_MPU6000_INT_CLR_ANYRD, .interrupt_en = PIOS_MPU6000_INTEN_DATA_RDY, .User_ctl = PIOS_MPU6000_USERCTL_FIFO_EN | PIOS_MPU6000_USERCTL_DIS_I2C, .Pwr_mgmt_clk = PIOS_MPU6000_PWRMGMT_PLL_X_CLK, .accel_range = PIOS_MPU6000_ACCEL_8G, - .gyro_range = PIOS_MPU6000_SCALE_500_DEG, + .gyro_range = PIOS_MPU6000_SCALE_2000_DEG, .filter = PIOS_MPU6000_LOWPASS_256_HZ, .orientation = PIOS_MPU6000_TOP_180DEG }; @@ -817,6 +820,7 @@ void PIOS_Board_Init(void) { PIOS_Assert(0); } PIOS_MPU6000_Init(pios_spi_gyro_id,0,&pios_mpu6000_cfg); + PIOS_MPU6000_CONFIG_Configure(); init_test = PIOS_MPU6000_Test(); #endif /* PIOS_INCLUDE_MPU6000 */ diff --git a/flight/Libraries/PyMite/pymite.mk b/flight/Libraries/PyMite/pymite.mk new file mode 100644 index 000000000..02da15a5d --- /dev/null +++ b/flight/Libraries/PyMite/pymite.mk @@ -0,0 +1,41 @@ +# +# Rules to add PYMite to a PiOS target +# + +PYMITE = $(FLIGHTLIB)/PyMite +PYMITELIB = $(PYMITE)/lib +PYMITEPLAT = $(PYMITE)/platform/openpilot +PYMITETOOLS = $(PYMITE)/tools +PYMITEVM = $(PYMITE)/vm +PYMITEINC = $(PYMITEVM) +PYMITEINC += $(PYMITEPLAT) +PYMITEINC += $(OUTDIR) + +# List C source files here. (C dependencies are automatically generated.) +# use file-extension c for "c-only"-files + +## PyMite files and modules +SRC += $(OUTDIR)/pmlib_img.c +SRC += $(OUTDIR)/pmlib_nat.c +SRC += $(OUTDIR)/pmlibusr_img.c +SRC += $(OUTDIR)/pmlibusr_nat.c +PYSRC += $(wildcard ${PYMITEVM}/*.c) +PYSRC += $(wildcard ${PYMITEPLAT}/*.c) +PYSRC += ${foreach MOD, ${PYMODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}} +SRC += $(PYSRC) + +EXTRAINCDIRS += $(PYMITEINC) + +# Generate intermediate code +gencode: ${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h + +$(PYSRC): gencode + +PYTHON = python + +# Generate code for PyMite +${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h: $(wildcard ${PYMITELIB}/*.py) $(wildcard ${PYMITEPLAT}/*.py) $(wildcard ${FLIGHTPLANLIB}/*.py) $(wildcard ${FLIGHTPLANS}/*.py) + @echo $(MSG_PYMITEINIT) $(call toprel, $@) + @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -s --memspace=flash -o $(OUTDIR)/pmlib_img.c --native-file=$(OUTDIR)/pmlib_nat.c $(PYMITELIB)/list.py $(PYMITELIB)/dict.py $(PYMITELIB)/__bi.py $(PYMITELIB)/sys.py $(PYMITELIB)/string.py $(wildcard $(FLIGHTPLANLIB)/*.py) + @$(PYTHON) $(PYMITETOOLS)/pmGenPmFeatures.py $(PYMITEPLAT)/pmfeatures.py > $(OUTDIR)/pmfeatures.h + @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -u -o $(OUTDIR)/pmlibusr_img.c --native-file=$(OUTDIR)/pmlibusr_nat.c $(FLIGHTPLANS)/test.py diff --git a/flight/PiOS/Common/pios_mpu6000.c b/flight/PiOS/Common/pios_mpu6000.c index f62d09859..9ccbb644e 100644 --- a/flight/PiOS/Common/pios_mpu6000.c +++ b/flight/PiOS/Common/pios_mpu6000.c @@ -31,7 +31,6 @@ /* Project Includes */ #include "pios.h" - #if defined(PIOS_INCLUDE_MPU6000) #include "fifo_buffer.h" @@ -48,6 +47,9 @@ struct mpu6000_dev { uint32_t slave_num; xQueueHandle queue; const struct pios_mpu6000_cfg * cfg; + enum pios_mpu6000_range gyro_range; + enum pios_mpu6000_accel_range accel_range; + enum pios_mpu6000_filter filter; enum pios_mpu6000_dev_magic magic; }; @@ -130,51 +132,45 @@ int32_t PIOS_MPU6000_Init(uint32_t spi_id, uint32_t slave_num, const struct pios * @brief Initialize the MPU6000 3-axis gyro sensor * \return none * \param[in] PIOS_MPU6000_ConfigTypeDef struct to be used to configure sensor. -* -*/ + * + */ static void PIOS_MPU6000_Config(struct pios_mpu6000_cfg const * cfg) { PIOS_MPU6000_Test(); - + // Reset chip - while (PIOS_MPU6000_SetReg(PIOS_MPU6000_PWR_MGMT_REG, 0x80) != 0); + while (PIOS_MPU6000_SetReg(PIOS_MPU6000_PWR_MGMT_REG, PIOS_MPU6000_PWRMGMT_IMU_RST) != 0); PIOS_DELAY_WaitmS(300); - + // Reset chip and fifo - while (PIOS_MPU6000_SetReg(PIOS_MPU6000_USER_CTRL_REG, 0x80 | 0x01 | 0x02 | 0x04) != 0); - + while (PIOS_MPU6000_SetReg(PIOS_MPU6000_USER_CTRL_REG, + PIOS_MPU6000_USERCTL_GYRO_RST | + PIOS_MPU6000_USERCTL_SIG_COND | + PIOS_MPU6000_USERCTL_FIFO_RST) != 0); + // Wait for reset to finish - while (PIOS_MPU6000_GetReg(PIOS_MPU6000_USER_CTRL_REG) & 0x07); - + while (PIOS_MPU6000_GetReg(PIOS_MPU6000_USER_CTRL_REG) & + (PIOS_MPU6000_USERCTL_GYRO_RST | + PIOS_MPU6000_USERCTL_SIG_COND | + PIOS_MPU6000_USERCTL_FIFO_RST)); + //Power management configuration - while (PIOS_MPU6000_SetReg(PIOS_MPU6000_PWR_MGMT_REG, cfg->Pwr_mgmt_clk) != 0) ; + while (PIOS_MPU6000_SetReg(PIOS_MPU6000_PWR_MGMT_REG, cfg->Pwr_mgmt_clk) != 0); // Interrupt configuration - while (PIOS_MPU6000_SetReg(PIOS_MPU6000_INT_CFG_REG, cfg->interrupt_cfg) != 0) ; + while (PIOS_MPU6000_SetReg(PIOS_MPU6000_INT_CFG_REG, cfg->interrupt_cfg) != 0); // Interrupt configuration - while (PIOS_MPU6000_SetReg(PIOS_MPU6000_INT_EN_REG, cfg->interrupt_en) != 0) ; + while (PIOS_MPU6000_SetReg(PIOS_MPU6000_INT_EN_REG, cfg->interrupt_en) != 0); // FIFO storage #if defined(PIOS_MPU6000_ACCEL) - // Set the accel scale - while (PIOS_MPU6000_SetReg(PIOS_MPU6000_ACCEL_CFG_REG, cfg->accel_range) != 0); - while (PIOS_MPU6000_SetReg(PIOS_MPU6000_FIFO_EN_REG, cfg->Fifo_store | PIOS_MPU6000_ACCEL_OUT) != 0); #else while (PIOS_MPU6000_SetReg(PIOS_MPU6000_FIFO_EN_REG, cfg->Fifo_store) != 0); #endif - - // Sample rate divider - while (PIOS_MPU6000_SetReg(PIOS_MPU6000_SMPLRT_DIV_REG, cfg->Smpl_rate_div) != 0) ; - - // Digital low-pass filter and scale - while (PIOS_MPU6000_SetReg(PIOS_MPU6000_DLPF_CFG_REG, cfg->filter) != 0) ; - - // Digital low-pass filter and scale - while (PIOS_MPU6000_SetReg(PIOS_MPU6000_GYRO_CFG_REG, cfg->gyro_range) != 0) ; - + PIOS_MPU6000_ConfigureRanges(cfg->gyro_range, cfg->accel_range, cfg->filter); // Interrupt configuration while (PIOS_MPU6000_SetReg(PIOS_MPU6000_USER_CTRL_REG, cfg->User_ctl) != 0) ; @@ -191,6 +187,42 @@ static void PIOS_MPU6000_Config(struct pios_mpu6000_cfg const * cfg) mpu6000_configured = true; } +/** + * @brief Configures Gyro, accel and Filter ranges/setings + * @return 0 if successful, -1 if device has not been initialized + */ +int32_t PIOS_MPU6000_ConfigureRanges( + enum pios_mpu6000_range gyroRange, + enum pios_mpu6000_accel_range accelRange, + enum pios_mpu6000_filter filterSetting + ) +{ + if(dev == NULL) + return -1; + PIOS_SPI_SetClockSpeed(dev->spi_id, PIOS_SPI_PRESCALER_256); + // update filter settings + while (PIOS_MPU6000_SetReg(PIOS_MPU6000_DLPF_CFG_REG, filterSetting) != 0); + + // Sample rate divider, chosen upon digital filtering settings + while (PIOS_MPU6000_SetReg(PIOS_MPU6000_SMPLRT_DIV_REG, + filterSetting == PIOS_MPU6000_LOWPASS_256_HZ ? + dev->cfg->Smpl_rate_div_no_dlp : dev->cfg->Smpl_rate_div_dlp) != 0); + + dev->filter = filterSetting; + + // Gyro range + while (PIOS_MPU6000_SetReg(PIOS_MPU6000_GYRO_CFG_REG, gyroRange) != 0); + + dev->gyro_range = gyroRange; +#if defined(PIOS_MPU6000_ACCEL) + // Set the accel range + while (PIOS_MPU6000_SetReg(PIOS_MPU6000_ACCEL_CFG_REG, accelRange) != 0); + + dev->accel_range = accelRange; +#endif + PIOS_SPI_SetClockSpeed(dev->spi_id, PIOS_SPI_PRESCALER_16); + return 0; +} /** * @brief Claim the SPI bus for the accel communications and select this chip @@ -322,7 +354,7 @@ xQueueHandle PIOS_MPU6000_GetQueue() float PIOS_MPU6000_GetScale() { - switch (dev->cfg->gyro_range) { + switch (dev->gyro_range) { case PIOS_MPU6000_SCALE_250_DEG: return 1.0f / 131.0f; case PIOS_MPU6000_SCALE_500_DEG: @@ -337,7 +369,7 @@ float PIOS_MPU6000_GetScale() float PIOS_MPU6000_GetAccelScale() { - switch (dev->cfg->accel_range) { + switch (dev->accel_range) { case PIOS_MPU6000_ACCEL_2G: return GRAV / 16384.0f; case PIOS_MPU6000_ACCEL_4G: @@ -411,20 +443,20 @@ bool PIOS_MPU6000_IRQHandler(void) mpu6000_interval_us = PIOS_DELAY_DiffuS(timeval); timeval = PIOS_DELAY_GetRaw(); - if(!mpu6000_configured) + if (!mpu6000_configured) return false; mpu6000_count = PIOS_MPU6000_FifoDepth(); - if(mpu6000_count < sizeof(struct pios_mpu6000_data)) + if (mpu6000_count < sizeof(struct pios_mpu6000_data)) return false; - - if(PIOS_MPU6000_ClaimBus() != 0) + + if (PIOS_MPU6000_ClaimBus() != 0) return false; - - uint8_t mpu6000_send_buf[1+sizeof(struct pios_mpu6000_data)] = {PIOS_MPU6000_FIFO_REG | 0x80, 0, 0, 0, 0, 0, 0, 0, 0}; - uint8_t mpu6000_rec_buf[1+sizeof(struct pios_mpu6000_data)]; - - if(PIOS_SPI_TransferBlock(dev->spi_id, &mpu6000_send_buf[0], &mpu6000_rec_buf[0], sizeof(mpu6000_send_buf), NULL) < 0) { + + uint8_t mpu6000_send_buf[1 + sizeof(struct pios_mpu6000_data) ] = {PIOS_MPU6000_FIFO_REG | 0x80, 0, 0, 0, 0, 0, 0, 0, 0}; + uint8_t mpu6000_rec_buf[1 + sizeof(struct pios_mpu6000_data) ]; + + if (PIOS_SPI_TransferBlock(dev->spi_id, &mpu6000_send_buf[0], &mpu6000_rec_buf[0], sizeof(mpu6000_send_buf), NULL) < 0) { PIOS_MPU6000_ReleaseBus(); mpu6000_fails++; return false; @@ -437,85 +469,86 @@ bool PIOS_MPU6000_IRQHandler(void) // In the case where extras samples backed up grabbed an extra if (mpu6000_count >= (sizeof(data) * 2)) { mpu6000_fifo_backup++; - if(PIOS_MPU6000_ClaimBus() != 0) - return false; - - if(PIOS_SPI_TransferBlock(dev->spi_id, &mpu6000_send_buf[0], &mpu6000_rec_buf[0], sizeof(mpu6000_send_buf), NULL) < 0) { + if (PIOS_MPU6000_ClaimBus() != 0) + return false; + + if (PIOS_SPI_TransferBlock(dev->spi_id, &mpu6000_send_buf[0], &mpu6000_rec_buf[0], sizeof(mpu6000_send_buf), NULL) < 0) { PIOS_MPU6000_ReleaseBus(); mpu6000_fails++; return false; } - + PIOS_MPU6000_ReleaseBus(); } - + // Rotate the sensor to OP convention. The datasheet defines X as towards the right // and Y as forward. OP convention transposes this. Also the Z is defined negatively // to our convention #if defined(PIOS_MPU6000_ACCEL) // Currently we only support rotations on top so switch X/Y accordingly - switch(dev->cfg->orientation) { - case PIOS_MPU6000_TOP_0DEG: - data.accel_y = mpu6000_rec_buf[1] << 8 | mpu6000_rec_buf[2]; // chip X - data.accel_x = mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]; // chip Y - data.gyro_y = mpu6000_rec_buf[9] << 8 | mpu6000_rec_buf[10]; // chip X - data.gyro_x = mpu6000_rec_buf[11] << 8 | mpu6000_rec_buf[12]; // chip Y - break; - case PIOS_MPU6000_TOP_90DEG: - data.accel_y = -(mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]); // chip Y - data.accel_x = mpu6000_rec_buf[1] << 8 | mpu6000_rec_buf[2]; // chip X - data.gyro_y = -(mpu6000_rec_buf[11] << 8 | mpu6000_rec_buf[12]); // chip Y - data.gyro_x = mpu6000_rec_buf[9] << 8 | mpu6000_rec_buf[10]; // chip X - break; - case PIOS_MPU6000_TOP_180DEG: - data.accel_y = -(mpu6000_rec_buf[1] << 8 | mpu6000_rec_buf[2]); // chip X - data.accel_x = -(mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]); // chip Y - data.gyro_y = -(mpu6000_rec_buf[9] << 8 | mpu6000_rec_buf[10]); // chip X - data.gyro_x = -(mpu6000_rec_buf[11] << 8 | mpu6000_rec_buf[12]); // chip Y - break; - case PIOS_MPU6000_TOP_270DEG: - data.accel_y = mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]; // chip Y - data.accel_x = -(mpu6000_rec_buf[1] << 8 | mpu6000_rec_buf[2]); // chip X - data.gyro_y = mpu6000_rec_buf[11] << 8 | mpu6000_rec_buf[12]; // chip Y - data.gyro_x = -(mpu6000_rec_buf[9] << 8 | mpu6000_rec_buf[10]); // chip X - break; + switch (dev->cfg->orientation) { + case PIOS_MPU6000_TOP_0DEG: + data.accel_y = mpu6000_rec_buf[1] << 8 | mpu6000_rec_buf[2]; // chip X + data.accel_x = mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]; // chip Y + data.gyro_y = mpu6000_rec_buf[9] << 8 | mpu6000_rec_buf[10]; // chip X + data.gyro_x = mpu6000_rec_buf[11] << 8 | mpu6000_rec_buf[12]; // chip Y + break; + case PIOS_MPU6000_TOP_90DEG: + // -1 to bring it back to -32768 +32767 range + data.accel_y = -1 - (mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]); // chip Y + data.accel_x = mpu6000_rec_buf[1] << 8 | mpu6000_rec_buf[2]; // chip X + data.gyro_y = -1 - (mpu6000_rec_buf[11] << 8 | mpu6000_rec_buf[12]); // chip Y + data.gyro_x = mpu6000_rec_buf[9] << 8 | mpu6000_rec_buf[10]; // chip X + break; + case PIOS_MPU6000_TOP_180DEG: + data.accel_y = -1 - (mpu6000_rec_buf[1] << 8 | mpu6000_rec_buf[2]); // chip X + data.accel_x = -1 - (mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]); // chip Y + data.gyro_y = -1 - (mpu6000_rec_buf[9] << 8 | mpu6000_rec_buf[10]); // chip X + data.gyro_x = -1 - (mpu6000_rec_buf[11] << 8 | mpu6000_rec_buf[12]); // chip Y + break; + case PIOS_MPU6000_TOP_270DEG: + data.accel_y = mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]; // chip Y + data.accel_x = -1 - (mpu6000_rec_buf[1] << 8 | mpu6000_rec_buf[2]); // chip X + data.gyro_y = mpu6000_rec_buf[11] << 8 | mpu6000_rec_buf[12]; // chip Y + data.gyro_x = -1 - (mpu6000_rec_buf[9] << 8 | mpu6000_rec_buf[10]); // chip X + break; } - data.gyro_z = -(mpu6000_rec_buf[13] << 8 | mpu6000_rec_buf[14]); - data.accel_z = -(mpu6000_rec_buf[5] << 8 | mpu6000_rec_buf[6]); + data.gyro_z = -1 - (mpu6000_rec_buf[13] << 8 | mpu6000_rec_buf[14]); + data.accel_z = -1 - (mpu6000_rec_buf[5] << 8 | mpu6000_rec_buf[6]); data.temperature = mpu6000_rec_buf[7] << 8 | mpu6000_rec_buf[8]; #else data.gyro_x = mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]; data.gyro_y = mpu6000_rec_buf[5] << 8 | mpu6000_rec_buf[6]; - switch(dev->cfg->orientation) { - case PIOS_MPU6000_TOP_0DEG: - data.gyro_y = mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]; - data.gyro_x = mpu6000_rec_buf[5] << 8 | mpu6000_rec_buf[6]; - break; - case PIOS_MPU6000_TOP_90DEG: - data.gyro_y = -(mpu6000_rec_buf[5] << 8 | mpu6000_rec_buf[6]); // chip Y - data.gyro_x = mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]; // chip X - break; - case PIOS_MPU6000_TOP_180DEG: - data.gyro_y = -(mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]); - data.gyro_x = -(mpu6000_rec_buf[5] << 8 | mpu6000_rec_buf[6]); - break; - case PIOS_MPU6000_TOP_270DEG: - data.gyro_y = mpu6000_rec_buf[5] << 8 | mpu6000_rec_buf[6]; // chip Y - data.gyro_x = -(mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]); // chip X - break; + switch (dev->cfg->orientation) { + case PIOS_MPU6000_TOP_0DEG: + data.gyro_y = mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]; + data.gyro_x = mpu6000_rec_buf[5] << 8 | mpu6000_rec_buf[6]; + break; + case PIOS_MPU6000_TOP_90DEG: + data.gyro_y = -1 - (mpu6000_rec_buf[5] << 8 | mpu6000_rec_buf[6]); // chip Y + data.gyro_x = mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]; // chip X + break; + case PIOS_MPU6000_TOP_180DEG: + data.gyro_y = -1 - (mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]); + data.gyro_x = -1 - (mpu6000_rec_buf[5] << 8 | mpu6000_rec_buf[6]); + break; + case PIOS_MPU6000_TOP_270DEG: + data.gyro_y = mpu6000_rec_buf[5] << 8 | mpu6000_rec_buf[6]; // chip Y + data.gyro_x = -1 - (mpu6000_rec_buf[3] << 8 | mpu6000_rec_buf[4]); // chip X + break; } - data.gyro_z = -(mpu6000_rec_buf[7] << 8 | mpu6000_rec_buf[8]); + data.gyro_z = -1 - (mpu6000_rec_buf[7] << 8 | mpu6000_rec_buf[8]); data.temperature = mpu6000_rec_buf[1] << 8 | mpu6000_rec_buf[2]; #endif - + portBASE_TYPE xHigherPriorityTaskWoken; xQueueSendToBackFromISR(dev->queue, (void *) &data, &xHigherPriorityTaskWoken); - + mpu6000_irq++; - + mpu6000_time_us = PIOS_DELAY_DiffuS(timeval); - - return xHigherPriorityTaskWoken == pdTRUE; + + return xHigherPriorityTaskWoken == pdTRUE; } #endif diff --git a/flight/PiOS/inc/pios_mpu6000.h b/flight/PiOS/inc/pios_mpu6000.h index 254f10192..1be368575 100644 --- a/flight/PiOS/inc/pios_mpu6000.h +++ b/flight/PiOS/inc/pios_mpu6000.h @@ -8,7 +8,7 @@ * * @file PIOS_MPU6000.h * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012. - * @brief MPU6000 3-axis gyor function headers + * @brief MPU6000 3-axis gyro function headers * @see The GNU Public License (GPL) Version 3 * ****************************************************************************** @@ -87,8 +87,10 @@ /* User control functionality */ #define PIOS_MPU6000_USERCTL_FIFO_EN 0X40 +#define PIOS_MPU6000_USERCTL_I2C_MST_EN 0x20 #define PIOS_MPU6000_USERCTL_DIS_I2C 0X10 -#define PIOS_MPU6000_USERCTL_FIFO_RST 0X02 +#define PIOS_MPU6000_USERCTL_FIFO_RST 0X04 +#define PIOS_MPU6000_USERCTL_SIG_COND 0X02 #define PIOS_MPU6000_USERCTL_GYRO_RST 0X01 /* Power management and clock selection */ @@ -146,8 +148,11 @@ struct pios_mpu6000_cfg { const struct pios_exti_cfg * exti_cfg; /* Pointer to the EXTI configuration */ uint8_t Fifo_store; /* FIFO storage of different readings (See datasheet page 31 for more details) */ - uint8_t Smpl_rate_div; /* Sample rate divider to use (See datasheet page 32 for more details) */ - uint8_t interrupt_cfg; /* Interrupt configuration (See datasheet page 35 for more details) */ + + /* Sample rate divider to use (See datasheet page 32 for more details).*/ + uint8_t Smpl_rate_div_no_dlp; /* used when no dlp is applied (fs=8KHz)*/ + uint8_t Smpl_rate_div_dlp; /* used when dlp is on (fs=1kHz)*/ + uint8_t interrupt_cfg; /* Interrupt configuration (See datasheet page 35 for more details) */ uint8_t interrupt_en; /* Interrupt configuration (See datasheet page 35 for more details) */ uint8_t User_ctl; /* User control settings (See datasheet page 41 for more details) */ uint8_t Pwr_mgmt_clk; /* Power management and clock selection (See datasheet page 32 for more details) */ @@ -159,6 +164,7 @@ struct pios_mpu6000_cfg { /* Public Functions */ extern int32_t PIOS_MPU6000_Init(uint32_t spi_id, uint32_t slave_num, const struct pios_mpu6000_cfg * new_cfg); +extern int32_t PIOS_MPU6000_ConfigureRanges(enum pios_mpu6000_range gyroRange, enum pios_mpu6000_accel_range accelRange,enum pios_mpu6000_filter filterSetting); extern xQueueHandle PIOS_MPU6000_GetQueue(); extern int32_t PIOS_MPU6000_ReadGyros(struct pios_mpu6000_data * buffer); extern int32_t PIOS_MPU6000_ReadID(); diff --git a/flight/PiOS/inc/pios_mpu6000_config.h b/flight/PiOS/inc/pios_mpu6000_config.h new file mode 100644 index 000000000..59e355c9a --- /dev/null +++ b/flight/PiOS/inc/pios_mpu6000_config.h @@ -0,0 +1,72 @@ +/** + ****************************************************************************** + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_MPU6000 OpenPilot layer configuration utilities + * @brief provides mpu6000 configuration helpers function + * @{ + * + * @file PIOS_MPU6000_CONFIG.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013. + * @brief MPU6000 UAVO-based configuration functions + * @see The GNU Public License (GPL) Version 3 + * + ****************************************************************************** + */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PIOS_MPU6000_CONFIG_H +#define PIOS_MPU6000_CONFIG_H + +#include "mpu6000settings.h" +#include "pios_mpu6000.h" + +#define PIOS_MPU6000_CONFIG_MAP_GYROSCALE(x) (x == MPU6000SETTINGS_GYROSCALE_SCALE_250 ? PIOS_MPU6000_SCALE_250_DEG : \ + x == MPU6000SETTINGS_GYROSCALE_SCALE_500 ? PIOS_MPU6000_SCALE_500_DEG : \ + x == MPU6000SETTINGS_GYROSCALE_SCALE_1000 ? PIOS_MPU6000_SCALE_1000_DEG : \ + PIOS_MPU6000_SCALE_2000_DEG) + +#define PIOS_MPU6000_CONFIG_MAP_ACCELSCALE(x) (x == MPU6000SETTINGS_ACCELSCALE_SCALE_2G ? PIOS_MPU6000_ACCEL_2G : \ + x == MPU6000SETTINGS_ACCELSCALE_SCALE_4G ? PIOS_MPU6000_ACCEL_4G : \ + x == MPU6000SETTINGS_ACCELSCALE_SCALE_16G ? PIOS_MPU6000_ACCEL_16G : \ + PIOS_MPU6000_ACCEL_8G) + +#define PIOS_MPU6000_CONFIG_MAP_FILTERSETTING(x) (x == MPU6000SETTINGS_FILTERSETTING_LOWPASS_188_HZ ? PIOS_MPU6000_LOWPASS_188_HZ : \ + x == MPU6000SETTINGS_FILTERSETTING_LOWPASS_98_HZ ? PIOS_MPU6000_LOWPASS_98_HZ : \ + x == MPU6000SETTINGS_FILTERSETTING_LOWPASS_42_HZ ? PIOS_MPU6000_LOWPASS_42_HZ : \ + x == MPU6000SETTINGS_FILTERSETTING_LOWPASS_20_HZ ? PIOS_MPU6000_LOWPASS_20_HZ : \ + x == MPU6000SETTINGS_FILTERSETTING_LOWPASS_10_HZ ? PIOS_MPU6000_LOWPASS_10_HZ : \ + x == MPU6000SETTINGS_FILTERSETTING_LOWPASS_5_HZ ? PIOS_MPU6000_LOWPASS_5_HZ : \ + PIOS_MPU6000_LOWPASS_256_HZ) +/** + * @brief Updates MPU6000 config based on Mpu6000Settings UAVO + * @returns 0 if succeed or -1 otherwise + */ +int32_t PIOS_MPU6000_CONFIG_Configure() +{ + Mpu6000SettingsInitialize(); + Mpu6000SettingsData mpu6000settings; + Mpu6000SettingsGet(&mpu6000settings); + return PIOS_MPU6000_ConfigureRanges( + PIOS_MPU6000_CONFIG_MAP_GYROSCALE (mpu6000settings.GyroScale), + PIOS_MPU6000_CONFIG_MAP_ACCELSCALE(mpu6000settings.AccelScale), + PIOS_MPU6000_CONFIG_MAP_FILTERSETTING(mpu6000settings.FilterSetting) + ); +} + +#endif /* PIOS_MPU6000_CONFIG_H */ + diff --git a/flight/RevoMini/Makefile b/flight/RevoMini/Makefile index 9ebf3f116..f2b97d08e 100644 --- a/flight/RevoMini/Makefile +++ b/flight/RevoMini/Makefile @@ -94,14 +94,6 @@ STMSPDSRCDIR = $(STMSPDDIR)/src STMSPDINCDIR = $(STMSPDDIR)/inc OPUAVOBJ = ../UAVObjects OPUAVOBJINC = $(OPUAVOBJ)/inc -PYMITE = $(FLIGHTLIB)/PyMite -PYMITELIB = $(PYMITE)/lib -PYMITEPLAT = $(PYMITE)/platform/openpilot -PYMITETOOLS = $(PYMITE)/tools -PYMITEVM = $(PYMITE)/vm -PYMITEINC = $(PYMITEVM) -PYMITEINC += $(PYMITEPLAT) -PYMITEINC += $(OUTDIR) FLIGHTPLANLIB = $(OPMODULEDIR)/FlightPlan/lib FLIGHTPLANS = $(OPMODULEDIR)/FlightPlan/flightplans HWDEFSINC = ../board_hw_defs/$(BOARD_NAME) @@ -113,19 +105,8 @@ include $(PIOSCOMMONLIB)/FreeRTOS/library.mk #include $(PIOSCOMMONLIB)/dosfs/library.mk include $(PIOSCOMMONLIB)/msheap/library.mk - -# List C source files here. (C dependencies are automatically generated.) -# use file-extension c for "c-only"-files - -## PyMite files and modules -SRC += $(OUTDIR)/pmlib_img.c -SRC += $(OUTDIR)/pmlib_nat.c -SRC += $(OUTDIR)/pmlibusr_img.c -SRC += $(OUTDIR)/pmlibusr_nat.c -PYSRC += $(wildcard ${PYMITEVM}/*.c) -PYSRC += $(wildcard ${PYMITEPLAT}/*.c) -PYSRC += ${foreach MOD, ${PYMODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}} -SRC += $(PYSRC) +## PYMite support +#include $(FLIGHTLIB)/PyMite/pymite.mk ## MODULES SRC += ${foreach MOD, ${MODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}} @@ -234,22 +215,8 @@ EXTRAINCDIRS += $(STMSPDINCDIR) EXTRAINCDIRS += $(CMSISDIR) EXTRAINCDIRS += $(OPUAVSYNTHDIR) EXTRAINCDIRS += $(BOOTINC) -EXTRAINCDIRS += $(PYMITEINC) EXTRAINCDIRS += $(HWDEFSINC) -# Generate intermediate code -gencode: ${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h - -$(PYSRC): gencode - -PYTHON = python - -# Generate code for PyMite -${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h: $(wildcard ${PYMITELIB}/*.py) $(wildcard ${PYMITEPLAT}/*.py) $(wildcard ${FLIGHTPLANLIB}/*.py) $(wildcard ${FLIGHTPLANS}/*.py) - @echo $(MSG_PYMITEINIT) $(call toprel, $@) - @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -s --memspace=flash -o $(OUTDIR)/pmlib_img.c --native-file=$(OUTDIR)/pmlib_nat.c $(PYMITELIB)/list.py $(PYMITELIB)/dict.py $(PYMITELIB)/__bi.py $(PYMITELIB)/sys.py $(PYMITELIB)/string.py $(wildcard $(FLIGHTPLANLIB)/*.py) - @$(PYTHON) $(PYMITETOOLS)/pmGenPmFeatures.py $(PYMITEPLAT)/pmfeatures.py > $(OUTDIR)/pmfeatures.h - @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -u -o $(OUTDIR)/pmlibusr_img.c --native-file=$(OUTDIR)/pmlibusr_nat.c $(FLIGHTPLANS)/test.py EXTRAINCDIRS += ${foreach MOD, ${MODULES} ${PYMODULES}, $(OPMODULEDIR)/${MOD}/inc} ${OPMODULEDIR}/System/inc # List any extra directories to look for library files here. @@ -390,7 +357,6 @@ LDFLAGS += $(addprefix -T,$(LINKER_SCRIPTS_APP)) # Define programs and commands. REMOVE = $(REMOVE_CMD) -f -PYTHON = python # List of all source files. ALLSRC = $(ASRCARM) $(ASRC) $(SRCARM) $(SRC) $(CPPSRCARM) $(CPPSRC) diff --git a/flight/RevoMini/System/pios_board.c b/flight/RevoMini/System/pios_board.c index 6f772acdf..380f5fe59 100644 --- a/flight/RevoMini/System/pios_board.c +++ b/flight/RevoMini/System/pios_board.c @@ -141,6 +141,7 @@ static const struct pios_ms5611_cfg pios_ms5611_cfg = { */ #if defined(PIOS_INCLUDE_MPU6000) #include "pios_mpu6000.h" +#include "pios_mpu6000_config.h" static const struct pios_exti_cfg pios_exti_mpu6000_cfg __exti_config = { .vector = PIOS_MPU6000_IRQHandler, .line = EXTI_Line4, @@ -175,14 +176,16 @@ static const struct pios_exti_cfg pios_exti_mpu6000_cfg __exti_config = { static const struct pios_mpu6000_cfg pios_mpu6000_cfg = { .exti_cfg = &pios_exti_mpu6000_cfg, .Fifo_store = PIOS_MPU6000_FIFO_TEMP_OUT | PIOS_MPU6000_FIFO_GYRO_X_OUT | PIOS_MPU6000_FIFO_GYRO_Y_OUT | PIOS_MPU6000_FIFO_GYRO_Z_OUT, - // Clock at 8 khz, downsampled by 8 for 1khz - .Smpl_rate_div = 11, + // Clock at 8 khz, downsampled by 12 for 666Hz + .Smpl_rate_div_no_dlp = 11, + // with dlp on output rate is 500Hz + .Smpl_rate_div_dlp = 1, .interrupt_cfg = PIOS_MPU6000_INT_CLR_ANYRD, .interrupt_en = PIOS_MPU6000_INTEN_DATA_RDY, .User_ctl = PIOS_MPU6000_USERCTL_FIFO_EN | PIOS_MPU6000_USERCTL_DIS_I2C, .Pwr_mgmt_clk = PIOS_MPU6000_PWRMGMT_PLL_X_CLK, .accel_range = PIOS_MPU6000_ACCEL_8G, - .gyro_range = PIOS_MPU6000_SCALE_500_DEG, + .gyro_range = PIOS_MPU6000_SCALE_2000_DEG, .filter = PIOS_MPU6000_LOWPASS_256_HZ, .orientation = PIOS_MPU6000_TOP_180DEG }; @@ -730,6 +733,7 @@ void PIOS_Board_Init(void) { #if defined(PIOS_INCLUDE_MPU6000) PIOS_MPU6000_Init(pios_spi_gyro_id,0, &pios_mpu6000_cfg); + PIOS_MPU6000_CONFIG_Configure(); #endif } diff --git a/flight/RevoMini/UAVObjects.inc b/flight/RevoMini/UAVObjects.inc index d07660a8f..6165f3d67 100644 --- a/flight/RevoMini/UAVObjects.inc +++ b/flight/RevoMini/UAVObjects.inc @@ -94,7 +94,7 @@ UAVOBJSRCFILENAMES += altitudeholdsettings UAVOBJSRCFILENAMES += altitudeholddesired UAVOBJSRCFILENAMES += waypoint UAVOBJSRCFILENAMES += waypointactive - +UAVOBJSRCFILENAMES += mpu6000settings UAVOBJSRCFILENAMES += txpidsettings UAVOBJSRC = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),$(UAVOBJSYNTHDIR)/$(UAVOBJSRCFILE).c ) diff --git a/flight/Revolution/Makefile b/flight/Revolution/Makefile index 67d7d04c6..c6f373086 100644 --- a/flight/Revolution/Makefile +++ b/flight/Revolution/Makefile @@ -117,14 +117,6 @@ OPUAVOBJ = ../UAVObjects OPUAVOBJINC = $(OPUAVOBJ)/inc BOOT = ../Bootloaders/INS BOOTINC = $(BOOT)/inc -PYMITE = $(FLIGHTLIB)/PyMite -PYMITELIB = $(PYMITE)/lib -PYMITEPLAT = $(PYMITE)/platform/openpilot -PYMITETOOLS = $(PYMITE)/tools -PYMITEVM = $(PYMITE)/vm -PYMITEINC = $(PYMITEVM) -PYMITEINC += $(PYMITEPLAT) -PYMITEINC += $(OUTDIR) FLIGHTPLANLIB = $(OPMODULEDIR)/FlightPlan/lib FLIGHTPLANS = $(OPMODULEDIR)/FlightPlan/flightplans HWDEFSINC = ../board_hw_defs/$(BOARD_NAME) @@ -136,20 +128,12 @@ include $(PIOSCOMMONLIB)/FreeRTOS/library.mk #include $(PIOSCOMMONLIB)/dosfs/library.mk include $(PIOSCOMMONLIB)/msheap/library.mk +## PYMite support +#include $(FLIGHTLIB)/PyMite/pymite.mk # List C source files here. (C dependencies are automatically generated.) # use file-extension c for "c-only"-files -## PyMite files and modules -SRC += $(OUTDIR)/pmlib_img.c -SRC += $(OUTDIR)/pmlib_nat.c -SRC += $(OUTDIR)/pmlibusr_img.c -SRC += $(OUTDIR)/pmlibusr_nat.c -PYSRC += $(wildcard ${PYMITEVM}/*.c) -PYSRC += $(wildcard ${PYMITEPLAT}/*.c) -PYSRC += ${foreach MOD, ${PYMODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}} -SRC += $(PYSRC) - ## MODULES SRC += ${foreach MOD, ${OPTMODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}} SRC += ${foreach MOD, ${MODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}} @@ -249,22 +233,8 @@ EXTRAINCDIRS += $(STMSPDINCDIR) EXTRAINCDIRS += $(CMSISDIR) EXTRAINCDIRS += $(OPUAVSYNTHDIR) EXTRAINCDIRS += $(BOOTINC) -EXTRAINCDIRS += $(PYMITEINC) EXTRAINCDIRS += $(HWDEFSINC) -# Generate intermediate code -gencode: ${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h - -$(PYSRC): gencode - -PYTHON = python - -# Generate code for PyMite -${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h: $(wildcard ${PYMITELIB}/*.py) $(wildcard ${PYMITEPLAT}/*.py) $(wildcard ${FLIGHTPLANLIB}/*.py) $(wildcard ${FLIGHTPLANS}/*.py) - @echo $(MSG_PYMITEINIT) $(call toprel, $@) - @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -s --memspace=flash -o $(OUTDIR)/pmlib_img.c --native-file=$(OUTDIR)/pmlib_nat.c $(PYMITELIB)/list.py $(PYMITELIB)/dict.py $(PYMITELIB)/__bi.py $(PYMITELIB)/sys.py $(PYMITELIB)/string.py $(wildcard $(FLIGHTPLANLIB)/*.py) - @$(PYTHON) $(PYMITETOOLS)/pmGenPmFeatures.py $(PYMITEPLAT)/pmfeatures.py > $(OUTDIR)/pmfeatures.h - @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -u -o $(OUTDIR)/pmlibusr_img.c --native-file=$(OUTDIR)/pmlibusr_nat.c $(FLIGHTPLANS)/test.py EXTRAINCDIRS += ${foreach MOD, ${OPTMODULES} ${MODULES} ${PYMODULES}, $(OPMODULEDIR)/${MOD}/inc} ${OPMODULEDIR}/System/inc # List any extra directories to look for library files here. diff --git a/flight/Revolution/System/pios_board.c b/flight/Revolution/System/pios_board.c index 37c9810b3..6f61c6625 100644 --- a/flight/Revolution/System/pios_board.c +++ b/flight/Revolution/System/pios_board.c @@ -182,6 +182,7 @@ static const struct pios_bma180_cfg pios_bma180_cfg = { */ #if defined(PIOS_INCLUDE_MPU6000) #include "pios_mpu6000.h" +#include "pios_mpu6000_config.h" static const struct pios_exti_cfg pios_exti_mpu6000_cfg __exti_config = { .vector = PIOS_MPU6000_IRQHandler, .line = EXTI_Line8, @@ -216,14 +217,16 @@ static const struct pios_exti_cfg pios_exti_mpu6000_cfg __exti_config = { static const struct pios_mpu6000_cfg pios_mpu6000_cfg = { .exti_cfg = &pios_exti_mpu6000_cfg, .Fifo_store = PIOS_MPU6000_FIFO_TEMP_OUT | PIOS_MPU6000_FIFO_GYRO_X_OUT | PIOS_MPU6000_FIFO_GYRO_Y_OUT | PIOS_MPU6000_FIFO_GYRO_Z_OUT, - // Clock at 8 khz, downsampled by 8 for 1khz - .Smpl_rate_div = 11, + // Clock at 8 khz, downsampled by 12 for 666Hz + .Smpl_rate_div_no_dlp = 11, + // with dlp on output rate is 500Hz + .Smpl_rate_div_dlp = 1, .interrupt_cfg = PIOS_MPU6000_INT_CLR_ANYRD, .interrupt_en = PIOS_MPU6000_INTEN_DATA_RDY, .User_ctl = PIOS_MPU6000_USERCTL_FIFO_EN | PIOS_MPU6000_USERCTL_DIS_I2C, .Pwr_mgmt_clk = PIOS_MPU6000_PWRMGMT_PLL_X_CLK, .accel_range = PIOS_MPU6000_ACCEL_8G, - .gyro_range = PIOS_MPU6000_SCALE_500_DEG, + .gyro_range = PIOS_MPU6000_SCALE_2000_DEG, .filter = PIOS_MPU6000_LOWPASS_256_HZ, .orientation = PIOS_MPU6000_TOP_0DEG }; @@ -872,6 +875,7 @@ void PIOS_Board_Init(void) { case 0x02: #if defined(PIOS_INCLUDE_MPU6000) PIOS_MPU6000_Init(pios_spi_gyro_id,0, &pios_mpu6000_cfg); + PIOS_MPU6000_CONFIG_Configure(); #endif break; default: diff --git a/flight/Revolution/UAVObjects.inc b/flight/Revolution/UAVObjects.inc index 545f6ecc7..8202dc1b2 100644 --- a/flight/Revolution/UAVObjects.inc +++ b/flight/Revolution/UAVObjects.inc @@ -94,6 +94,7 @@ UAVOBJSRCFILENAMES += altitudeholdsettings UAVOBJSRCFILENAMES += altitudeholddesired UAVOBJSRCFILENAMES += waypoint UAVOBJSRCFILENAMES += waypointactive +UAVOBJSRCFILENAMES += mpu6000settings UAVOBJSRC = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),$(UAVOBJSYNTHDIR)/$(UAVOBJSRCFILE).c ) UAVOBJDEFINE = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),-DUAVOBJ_INIT_$(UAVOBJSRCFILE) ) diff --git a/flight/SimPosix/Makefile b/flight/SimPosix/Makefile index 82c814c92..e2e7b777c 100644 --- a/flight/SimPosix/Makefile +++ b/flight/SimPosix/Makefile @@ -85,14 +85,6 @@ OPUAVOBJ = ../UAVObjects OPUAVOBJINC = $(OPUAVOBJ)/inc BOOT = BOOTINC = -PYMITE = $(FLIGHTLIB)/PyMite -PYMITELIB = $(PYMITE)/lib -PYMITEPLAT = $(PYMITE)/platform/openpilot -PYMITETOOLS = $(PYMITE)/tools -PYMITEVM = $(PYMITE)/vm -PYMITEINC = $(PYMITEVM) -PYMITEINC += $(PYMITEPLAT) -PYMITEINC += $(OUTDIR) FLIGHTPLANLIB = $(OPMODULEDIR)/FlightPlan/lib FLIGHTPLANS = $(OPMODULEDIR)/FlightPlan/flightplans HWDEFSINC = ../board_hw_defs/$(BOARD_NAME) @@ -104,20 +96,12 @@ include $(PIOSCOMMONLIB)/FreeRTOS/library.mk #include $(PIOSCOMMONLIB)/dosfs/library.mk #include $(PIOSCOMMONLIB)/msheap/library.mk +## PYMite support +#include $(FLIGHTLIB)/PyMite/pymite.mk # List C source files here. (C dependencies are automatically generated.) # use file-extension c for "c-only"-files -## PyMite files and modules -SRC += $(OUTDIR)/pmlib_img.c -SRC += $(OUTDIR)/pmlib_nat.c -SRC += $(OUTDIR)/pmlibusr_img.c -SRC += $(OUTDIR)/pmlibusr_nat.c -PYSRC += $(wildcard ${PYMITEVM}/*.c) -PYSRC += $(wildcard ${PYMITEPLAT}/*.c) -PYSRC += ${foreach MOD, ${PYMODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}} -SRC += $(PYSRC) - ## MODULES SRC += ${foreach MOD, ${MODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}} SRC += ${OUTDIR}/InitMods.c @@ -207,22 +191,8 @@ EXTRAINCDIRS += $(PIOSBOARDS) EXTRAINCDIRS += $(CMSISDIR) EXTRAINCDIRS += $(OPUAVSYNTHDIR) EXTRAINCDIRS += $(BOOTINC) -EXTRAINCDIRS += $(PYMITEINC) EXTRAINCDIRS += $(HWDEFSINC) -# Generate intermediate code -gencode: ${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h - -$(PYSRC): gencode - -PYTHON = python - -# Generate code for PyMite -${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h: $(wildcard ${PYMITELIB}/*.py) $(wildcard ${PYMITEPLAT}/*.py) $(wildcard ${FLIGHTPLANLIB}/*.py) $(wildcard ${FLIGHTPLANS}/*.py) - @echo $(MSG_PYMITEINIT) $(call toprel, $@) - @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -s --memspace=flash -o $(OUTDIR)/pmlib_img.c --native-file=$(OUTDIR)/pmlib_nat.c $(PYMITELIB)/list.py $(PYMITELIB)/dict.py $(PYMITELIB)/__bi.py $(PYMITELIB)/sys.py $(PYMITELIB)/string.py $(wildcard $(FLIGHTPLANLIB)/*.py) - @$(PYTHON) $(PYMITETOOLS)/pmGenPmFeatures.py $(PYMITEPLAT)/pmfeatures.py > $(OUTDIR)/pmfeatures.h - @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -u -o $(OUTDIR)/pmlibusr_img.c --native-file=$(OUTDIR)/pmlibusr_nat.c $(FLIGHTPLANS)/test.py EXTRAINCDIRS += ${foreach MOD, ${MODULES} ${PYMODULES}, $(OPMODULEDIR)/${MOD}/inc} ${OPMODULEDIR}/System/inc # List any extra directories to look for library files here. @@ -366,7 +336,6 @@ LDFLAGS += $(addprefix -T,$(LINKER_SCRIPTS_APP)) # Define programs and commands. REMOVE = $(REMOVE_CMD) -f -PYTHON = python # List of all source files. ALLSRC = $(ASRCARM) $(ASRC) $(SRCARM) $(SRC) $(CPPSRCARM) $(CPPSRC) diff --git a/flight/board_hw_defs/revomini/board_hw_defs.c b/flight/board_hw_defs/revomini/board_hw_defs.c index 7375d367a..538131b91 100644 --- a/flight/board_hw_defs/revomini/board_hw_defs.c +++ b/flight/board_hw_defs/revomini/board_hw_defs.c @@ -1281,13 +1281,13 @@ static const struct pios_tim_channel pios_tim_servoport_all_pins[] = { .pin = { .gpio = GPIOA, .init = { - .GPIO_Pin = GPIO_Pin_1, + .GPIO_Pin = GPIO_Pin_0, .GPIO_Speed = GPIO_Speed_2MHz, .GPIO_Mode = GPIO_Mode_AF, .GPIO_OType = GPIO_OType_PP, .GPIO_PuPd = GPIO_PuPd_UP }, - .pin_source = GPIO_PinSource1, + .pin_source = GPIO_PinSource0, }, .remap = GPIO_AF_TIM5, }, diff --git a/ground/openpilotgcs/src/plugins/config/config.pro b/ground/openpilotgcs/src/plugins/config/config.pro index 0bb6cdbcc..d36c2b2a9 100644 --- a/ground/openpilotgcs/src/plugins/config/config.pro +++ b/ground/openpilotgcs/src/plugins/config/config.pro @@ -17,7 +17,6 @@ HEADERS += configplugin.h \ configinputwidget.h \ configoutputwidget.h \ configvehicletypewidget.h \ - config_pro_hw_widget.h \ config_cc_hw_widget.h \ configccattitudewidget.h \ configpipxtremewidget.h \ @@ -39,7 +38,7 @@ HEADERS += configplugin.h \ config_global.h \ mixercurve.h \ dblspindelegate.h \ - configautotunewidget.h + configrevohwwidget.h SOURCES += configplugin.cpp \ configgadgetconfiguration.cpp \ configgadgetwidget.cpp \ @@ -50,7 +49,6 @@ SOURCES += configplugin.cpp \ configinputwidget.cpp \ configoutputwidget.cpp \ configvehicletypewidget.cpp \ - config_pro_hw_widget.cpp \ config_cc_hw_widget.cpp \ configccattitudewidget.cpp \ configstabilizationwidget.cpp \ @@ -73,10 +71,9 @@ SOURCES += configplugin.cpp \ cfg_vehicletypes/vehicleconfig.cpp \ mixercurve.cpp \ dblspindelegate.cpp \ - configautotunewidget.cpp + configrevohwwidget.cpp FORMS += airframe.ui \ cc_hw_settings.ui \ - pro_hw_settings.ui \ ccpm.ui \ stabilization.ui \ input.ui \ @@ -91,7 +88,7 @@ FORMS += airframe.ui \ txpid.ui \ pipxtreme.ui \ mixercurve.ui \ - autotune.ui + configrevohwwidget.ui RESOURCES += configgadget.qrc diff --git a/ground/openpilotgcs/src/plugins/config/config_pro_hw_widget.cpp b/ground/openpilotgcs/src/plugins/config/config_pro_hw_widget.cpp deleted file mode 100644 index 0f050cbc2..000000000 --- a/ground/openpilotgcs/src/plugins/config/config_pro_hw_widget.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/** - ****************************************************************************** - * - * @file configtelemetrywidget.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup ConfigPlugin Config Plugin - * @{ - * @brief The Configuration Gadget used to update settings in the firmware - *****************************************************************************/ -/* - * 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 "config_pro_hw_widget.h" - -#include -#include -#include -#include -#include -#include - - -ConfigProHWWidget::ConfigProHWWidget(QWidget *parent) : ConfigTaskWidget(parent) -{ - m_telemetry = new Ui_PRO_HW_Widget(); - m_telemetry->setupUi(this); - - addApplySaveButtons(m_telemetry->saveTelemetryToRAM,m_telemetry->saveTelemetryToSD); - addUAVObjectToWidgetRelation("HwSettings","TelemetrySpeed",m_telemetry->telemetrySpeed); - enableControls(false); - populateWidgets(); - refreshWidgetsValues(NULL); -} - -ConfigProHWWidget::~ConfigProHWWidget() -{ - // Do nothing -} - - -/** - Request telemetry settings from the board - */ -void ConfigProHWWidget::refreshValues() -{ -} diff --git a/ground/openpilotgcs/src/plugins/config/configgadget.qrc b/ground/openpilotgcs/src/plugins/config/configgadget.qrc index ff81d79fb..a5b006745 100644 --- a/ground/openpilotgcs/src/plugins/config/configgadget.qrc +++ b/ground/openpilotgcs/src/plugins/config/configgadget.qrc @@ -30,5 +30,6 @@ images/camstab_normal.png images/pipx-selected.png images/pipx-normal.png + images/revolution_top.png diff --git a/ground/openpilotgcs/src/plugins/config/configgadgetwidget.cpp b/ground/openpilotgcs/src/plugins/config/configgadgetwidget.cpp index 6aea1ce17..ab50ffbdc 100644 --- a/ground/openpilotgcs/src/plugins/config/configgadgetwidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/configgadgetwidget.cpp @@ -32,10 +32,9 @@ #include "configinputwidget.h" #include "configoutputwidget.h" #include "configstabilizationwidget.h" -#include "configautotunewidget.h" #include "configcamerastabilizationwidget.h" #include "configtxpidwidget.h" -#include "config_pro_hw_widget.h" +#include "configrevohwwidget.h" #include "config_cc_hw_widget.h" #include "configpipxtremewidget.h" #include "configrevowidget.h" @@ -103,12 +102,6 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent) qwd = new ConfigStabilizationWidget(this); ftw->insertTab(ConfigGadgetWidget::stabilization, qwd, *icon, QString("Stabilization")); - icon = new QIcon(); - icon->addFile(":/configgadget/images/autotune_normal.png", QSize(), QIcon::Normal, QIcon::Off); - icon->addFile(":/configgadget/images/autotune_selected.png", QSize(), QIcon::Selected, QIcon::Off); - qwd = new ConfigAutotuneWidget(this); - ftw->insertTab(ConfigGadgetWidget::autotune, qwd, *icon, QString("Autotune")); - icon = new QIcon(); icon->addFile(":/configgadget/images/camstab_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/camstab_selected.png", QSize(), QIcon::Selected, QIcon::Off); @@ -136,7 +129,7 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent) } help = 0; - connect(ftw,SIGNAL(currentAboutToShow(int,bool*)),this,SLOT(tabAboutToChange(int,bool*)));//,Qt::BlockingQueuedConnection); + connect(ftw,SIGNAL(currentAboutToShow(int,bool*)), this, SLOT(tabAboutToChange(int,bool*))); // Connect to the PipXStatus object updates UAVObjectManager *objManager = pm->getObject(); @@ -173,20 +166,21 @@ void ConfigGadgetWidget::resizeEvent(QResizeEvent *event) void ConfigGadgetWidget::onAutopilotDisconnect() { ftw->setCurrentIndex(ConfigGadgetWidget::hardware); - ftw->removeTab(ConfigGadgetWidget::sensors); QIcon *icon = new QIcon(); icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected, QIcon::Off); QWidget *qwd = new DefaultAttitudeWidget(this); + ftw->removeTab(ConfigGadgetWidget::sensors); ftw->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("INS")); - ftw->removeTab(ConfigGadgetWidget::hardware); icon = new QIcon(); icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected, QIcon::Off); qwd = new DefaultHwSettingsWidget(this); + ftw->removeTab(ConfigGadgetWidget::hardware); ftw->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString("Hardware")); + ftw->setCurrentIndex(ConfigGadgetWidget::hardware); emit autopilotDisconnected(); @@ -203,40 +197,39 @@ void ConfigGadgetWidget::onAutopilotConnect() { int board = utilMngr->getBoardModel(); if ((board & 0xff00) == 1024) { // CopterControl family - // Delete the INS panel, replace with CC Panel: - ftw->setCurrentIndex(ConfigGadgetWidget::hardware); - ftw->removeTab(ConfigGadgetWidget::sensors); QIcon *icon = new QIcon(); icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected, QIcon::Off); QWidget *qwd = new ConfigCCAttitudeWidget(this); - ftw->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("INS")); - ftw->removeTab(ConfigGadgetWidget::hardware); + ftw->removeTab(ConfigGadgetWidget::sensors); + ftw->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("CopterControl")); icon = new QIcon(); icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected, QIcon::Off); qwd = new ConfigCCHWWidget(this); + ftw->removeTab(ConfigGadgetWidget::hardware); ftw->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString("Hardware")); + ftw->setCurrentIndex(ConfigGadgetWidget::hardware); } else if ((board & 0xff00) == 0x0900) { - // Revolution sensor calibration - ftw->setCurrentIndex(ConfigGadgetWidget::hardware); - ftw->removeTab(ConfigGadgetWidget::sensors); + // Revolution family QIcon *icon = new QIcon(); icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off); icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected, QIcon::Off); QWidget *qwd = new ConfigRevoWidget(this); - ftw->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("Revo")); - ftw->removeTab(ConfigGadgetWidget::hardware); + ftw->removeTab(ConfigGadgetWidget::sensors); + ftw->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("Revolution")); icon = new QIcon(); icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal, QIcon::Off); - icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Normal, QIcon::On); - qwd = new ConfigProHWWidget(this); + icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected, QIcon::Off); + qwd = new ConfigRevoHWWidget(this); + ftw->removeTab(ConfigGadgetWidget::hardware); ftw->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString("Hardware")); + ftw->setCurrentIndex(ConfigGadgetWidget::hardware); } else { //Unknown board diff --git a/ground/openpilotgcs/src/plugins/config/configgadgetwidget.h b/ground/openpilotgcs/src/plugins/config/configgadgetwidget.h index 304c557b4..24209e1cf 100644 --- a/ground/openpilotgcs/src/plugins/config/configgadgetwidget.h +++ b/ground/openpilotgcs/src/plugins/config/configgadgetwidget.h @@ -48,7 +48,7 @@ class ConfigGadgetWidget: public QWidget public: ConfigGadgetWidget(QWidget *parent = 0); ~ConfigGadgetWidget(); - enum widgetTabs {hardware=0, aircraft, input, output, sensors, stabilization, camerastabilization, txpid, oplink, autotune}; + enum widgetTabs {hardware=0, aircraft, input, output, sensors, stabilization, camerastabilization, txpid, oplink}; void startInputWizard(); public slots: diff --git a/ground/openpilotgcs/src/plugins/config/configrevohwwidget.cpp b/ground/openpilotgcs/src/plugins/config/configrevohwwidget.cpp new file mode 100644 index 000000000..6564819a7 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/config/configrevohwwidget.cpp @@ -0,0 +1,297 @@ +/** + ****************************************************************************** + * + * @file configrevohwwidget.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup ConfigPlugin Config Plugin + * @{ + * @brief Revolution hardware 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 "configrevohwwidget.h" + +#include +#include +#include +#include "hwsettings.h" +#include +#include + + +ConfigRevoHWWidget::ConfigRevoHWWidget(QWidget *parent) : ConfigTaskWidget(parent) +{ + m_ui = new Ui_RevoHWWidget(); + m_ui->setupUi(this); + + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); + Core::Internal::GeneralSettings *settings = pm->getObject(); + if(!settings->useExpertMode()) { + m_ui->saveTelemetryToRAM->setEnabled(false); + m_ui->saveTelemetryToRAM->setVisible(false); + } + + addApplySaveButtons(m_ui->saveTelemetryToRAM, m_ui->saveTelemetryToSD); + + addUAVObjectToWidgetRelation("HwSettings","RM_FlexiPort",m_ui->cbFlexi); + addUAVObjectToWidgetRelation("HwSettings","RM_MainPort",m_ui->cbMain); + addUAVObjectToWidgetRelation("HwSettings","RM_RcvrPort",m_ui->cbRcvr); + + addUAVObjectToWidgetRelation("HwSettings","USB_HIDPort",m_ui->cbUSBHIDFunction); + addUAVObjectToWidgetRelation("HwSettings","USB_VCPPort",m_ui->cbUSBVCPFunction); + addUAVObjectToWidgetRelation("HwSettings","ComUsbBridgeSpeed",m_ui->cbUSBVCPSpeed); + + addUAVObjectToWidgetRelation("HwSettings","TelemetrySpeed",m_ui->cbFlexiTelemSpeed); + addUAVObjectToWidgetRelation("HwSettings","GPSSpeed",m_ui->cbFlexiGPSSpeed); + addUAVObjectToWidgetRelation("HwSettings","ComUsbBridgeSpeed",m_ui->cbFlexiComSpeed); + + addUAVObjectToWidgetRelation("HwSettings","TelemetrySpeed",m_ui->cbMainTelemSpeed); + addUAVObjectToWidgetRelation("HwSettings","GPSSpeed",m_ui->cbMainGPSSpeed); + addUAVObjectToWidgetRelation("HwSettings","ComUsbBridgeSpeed",m_ui->cbMainComSpeed); + + addUAVObjectToWidgetRelation("HwSettings","RadioPort",m_ui->cbModem); + + connect(m_ui->cchwHelp,SIGNAL(clicked()),this,SLOT(openHelp())); + + setupCustomCombos(); + enableControls(true); + populateWidgets(); + refreshWidgetsValues(); + forceConnectedState(); +} + +ConfigRevoHWWidget::~ConfigRevoHWWidget() +{ + // Do nothing +} + +void ConfigRevoHWWidget::setupCustomCombos() +{ + connect(m_ui->cbUSBHIDFunction, SIGNAL(currentIndexChanged(int)), this, SLOT(usbHIDPortChanged(int))); + connect(m_ui->cbUSBVCPFunction, SIGNAL(currentIndexChanged(int)), this, SLOT(usbVCPPortChanged(int))); + + m_ui->cbSonar->addItem(tr("Disabled")); + m_ui->cbSonar->setCurrentIndex(0); + m_ui->cbSonar->setEnabled(false); + + connect(m_ui->cbFlexi, SIGNAL(currentIndexChanged(int)), this, SLOT(flexiPortChanged(int))); + connect(m_ui->cbMain, SIGNAL(currentIndexChanged(int)), this, SLOT(mainPortChanged(int))); + connect(m_ui->cbModem, SIGNAL(currentIndexChanged(int)), this, SLOT(modemPortChanged(int))); + +} + +void ConfigRevoHWWidget::refreshWidgetsValues(UAVObject *obj) +{ + ConfigTaskWidget::refreshWidgetsValues(obj); + usbVCPPortChanged(0); + mainPortChanged(0); + flexiPortChanged(0); +} + +void ConfigRevoHWWidget::updateObjectsFromWidgets() +{ + ConfigTaskWidget::updateObjectsFromWidgets(); + + HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager()); + HwSettings::DataFields data = hwSettings->getData(); + + // If any port is configured to be GPS port, enable GPS module if it is not enabled. + // Otherwise disable GPS module. + if(m_ui->cbFlexi->currentIndex() == HwSettings::RM_FLEXIPORT_GPS || m_ui->cbMain->currentIndex() == HwSettings::RM_MAINPORT_GPS) { + data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = HwSettings::OPTIONALMODULES_ENABLED; + } + else { + data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = HwSettings::OPTIONALMODULES_DISABLED; + } + + // If any port is configured to be ComBridge port, enable UsbComBridge module if it is not enabled. + // Otherwise disable UsbComBridge module. + if(m_ui->cbFlexi->currentIndex() == HwSettings::RM_FLEXIPORT_COMBRIDGE || m_ui->cbMain->currentIndex() == HwSettings::RM_MAINPORT_COMBRIDGE || + m_ui->cbUSBVCPFunction->currentIndex() == HwSettings::USB_VCPPORT_COMBRIDGE) { + data.OptionalModules[HwSettings::OPTIONALMODULES_COMUSBBRIDGE] = HwSettings::OPTIONALMODULES_ENABLED; + } + else { + data.OptionalModules[HwSettings::OPTIONALMODULES_COMUSBBRIDGE] = HwSettings::OPTIONALMODULES_DISABLED; + } + + hwSettings->setData(data); +} + +void ConfigRevoHWWidget::usbVCPPortChanged(int index) +{ + Q_UNUSED(index); + + bool vcpComBridgeEnabled = m_ui->cbUSBVCPFunction->currentIndex() == HwSettings::USB_VCPPORT_COMBRIDGE; + + m_ui->lblUSBVCPSpeed->setVisible(vcpComBridgeEnabled); + m_ui->cbUSBVCPSpeed->setVisible(vcpComBridgeEnabled); + + if(!vcpComBridgeEnabled && m_ui->cbFlexi->currentIndex() == HwSettings::RM_FLEXIPORT_COMBRIDGE) { + m_ui->cbFlexi->setCurrentIndex(HwSettings::RM_FLEXIPORT_DISABLED); + } + m_ui->cbFlexi->model()->setData(m_ui->cbFlexi->model()->index(HwSettings::RM_FLEXIPORT_COMBRIDGE, 0), + !vcpComBridgeEnabled ? QVariant(0) : QVariant(1|32), Qt::UserRole - 1); + + if(!vcpComBridgeEnabled && m_ui->cbMain->currentIndex() == HwSettings::RM_MAINPORT_COMBRIDGE) { + m_ui->cbMain->setCurrentIndex(HwSettings::RM_MAINPORT_DISABLED); + } + m_ui->cbMain->model()->setData(m_ui->cbMain->model()->index(HwSettings::RM_MAINPORT_COMBRIDGE, 0), + !vcpComBridgeEnabled ? QVariant(0) : QVariant(1|32), Qt::UserRole - 1); + + //_DEBUGCONSOLE modes are mutual exclusive + if(m_ui->cbUSBVCPFunction->currentIndex() == HwSettings::USB_VCPPORT_DEBUGCONSOLE) { + if(m_ui->cbMain->currentIndex() == HwSettings::RM_MAINPORT_DEBUGCONSOLE) { + m_ui->cbMain->setCurrentIndex(HwSettings::RM_MAINPORT_DISABLED); + } + if(m_ui->cbFlexi->currentIndex() == HwSettings::RM_FLEXIPORT_DEBUGCONSOLE) { + m_ui->cbFlexi->setCurrentIndex(HwSettings::RM_FLEXIPORT_DISABLED); + } + } + + //_USBTELEMETRY modes are mutual exclusive + if(m_ui->cbUSBVCPFunction->currentIndex() == HwSettings::USB_VCPPORT_USBTELEMETRY) { + if(m_ui->cbUSBHIDFunction->currentIndex() == HwSettings::USB_HIDPORT_USBTELEMETRY) { + m_ui->cbUSBHIDFunction->setCurrentIndex(HwSettings::USB_HIDPORT_DISABLED); + } + } +} + +void ConfigRevoHWWidget::usbHIDPortChanged(int index) +{ + Q_UNUSED(index); + + //_USBTELEMETRY modes are mutual exclusive + if(m_ui->cbUSBHIDFunction->currentIndex() == HwSettings::USB_HIDPORT_USBTELEMETRY) { + if(m_ui->cbUSBVCPFunction->currentIndex() == HwSettings::USB_VCPPORT_USBTELEMETRY) { + m_ui->cbUSBVCPFunction->setCurrentIndex(HwSettings::USB_VCPPORT_DISABLED); + } + } +} + +void ConfigRevoHWWidget::flexiPortChanged(int index) +{ + Q_UNUSED(index); + + m_ui->cbFlexiTelemSpeed->setVisible(false); + m_ui->cbFlexiGPSSpeed->setVisible(false); + m_ui->cbFlexiComSpeed->setVisible(false); + m_ui->lblFlexiSpeed->setVisible(true); + + switch(m_ui->cbFlexi->currentIndex()) + { + case HwSettings::RM_FLEXIPORT_TELEMETRY: + m_ui->cbFlexiTelemSpeed->setVisible(true); + if(m_ui->cbMain->currentIndex() == HwSettings::RM_MAINPORT_TELEMETRY) { + m_ui->cbMain->setCurrentIndex(HwSettings::RM_MAINPORT_DISABLED); + } + if(m_ui->cbModem->currentIndex() == HwSettings::RADIOPORT_TELEMETRY) { + m_ui->cbModem->setCurrentIndex(HwSettings::RADIOPORT_DISABLED); + } + break; + case HwSettings::RM_FLEXIPORT_GPS: + m_ui->cbFlexiGPSSpeed->setVisible(true); + if(m_ui->cbMain->currentIndex() == HwSettings::RM_MAINPORT_GPS) { + m_ui->cbMain->setCurrentIndex(HwSettings::RM_MAINPORT_DISABLED); + } + break; + case HwSettings::RM_FLEXIPORT_COMBRIDGE: + m_ui->cbFlexiComSpeed->setVisible(true); + if(m_ui->cbMain->currentIndex() == HwSettings::RM_MAINPORT_COMBRIDGE) { + m_ui->cbMain->setCurrentIndex(HwSettings::RM_MAINPORT_DISABLED); + } + break; + case HwSettings::RM_FLEXIPORT_DEBUGCONSOLE: + m_ui->cbFlexiComSpeed->setVisible(true); + if(m_ui->cbMain->currentIndex() == HwSettings::RM_MAINPORT_DEBUGCONSOLE) { + m_ui->cbMain->setCurrentIndex(HwSettings::RM_MAINPORT_DISABLED); + } + if(m_ui->cbUSBVCPFunction->currentIndex() == HwSettings::USB_VCPPORT_DEBUGCONSOLE) { + m_ui->cbUSBVCPFunction->setCurrentIndex(HwSettings::USB_VCPPORT_DISABLED); + } + break; + default: + m_ui->lblFlexiSpeed->setVisible(false); + break; + } +} + +void ConfigRevoHWWidget::mainPortChanged(int index) +{ + Q_UNUSED(index); + + m_ui->cbMainTelemSpeed->setVisible(false); + m_ui->cbMainGPSSpeed->setVisible(false); + m_ui->cbMainComSpeed->setVisible(false); + m_ui->lblMainSpeed->setVisible(true); + + switch(m_ui->cbMain->currentIndex()) + { + case HwSettings::RM_MAINPORT_TELEMETRY: + m_ui->cbMainTelemSpeed->setVisible(true); + if(m_ui->cbFlexi->currentIndex() == HwSettings::RM_FLEXIPORT_TELEMETRY) { + m_ui->cbFlexi->setCurrentIndex(HwSettings::RM_FLEXIPORT_DISABLED); + } + if(m_ui->cbModem->currentIndex() == HwSettings::RADIOPORT_TELEMETRY) { + m_ui->cbModem->setCurrentIndex(HwSettings::RADIOPORT_DISABLED); + } + break; + case HwSettings::RM_MAINPORT_GPS: + m_ui->cbMainGPSSpeed->setVisible(true); + if(m_ui->cbFlexi->currentIndex() == HwSettings::RM_FLEXIPORT_GPS) { + m_ui->cbFlexi->setCurrentIndex(HwSettings::RM_FLEXIPORT_DISABLED); + } + break; + case HwSettings::RM_MAINPORT_COMBRIDGE: + m_ui->cbMainComSpeed->setVisible(true); + if(m_ui->cbFlexi->currentIndex() == HwSettings::RM_FLEXIPORT_COMBRIDGE) { + m_ui->cbFlexi->setCurrentIndex(HwSettings::RM_FLEXIPORT_DISABLED); + } + break; + case HwSettings::RM_MAINPORT_DEBUGCONSOLE: + m_ui->cbMainComSpeed->setVisible(true); + if(m_ui->cbFlexi->currentIndex() == HwSettings::RM_FLEXIPORT_DEBUGCONSOLE) { + m_ui->cbFlexi->setCurrentIndex(HwSettings::RM_FLEXIPORT_DISABLED); + } + if(m_ui->cbUSBVCPFunction->currentIndex() == HwSettings::USB_VCPPORT_DEBUGCONSOLE) { + m_ui->cbUSBVCPFunction->setCurrentIndex(HwSettings::USB_VCPPORT_DISABLED); + } + break; + default: + m_ui->lblMainSpeed->setVisible(false); + break; + } +} + +void ConfigRevoHWWidget::modemPortChanged(int index) +{ + Q_UNUSED(index); + + if(m_ui->cbModem->currentIndex()== HwSettings::RADIOPORT_TELEMETRY) { + if(m_ui->cbMain->currentIndex() == HwSettings::RM_MAINPORT_TELEMETRY) { + m_ui->cbMain->setCurrentIndex(HwSettings::RM_MAINPORT_DISABLED); + } + if(m_ui->cbFlexi->currentIndex() == HwSettings::RM_FLEXIPORT_TELEMETRY) { + m_ui->cbFlexi->setCurrentIndex(HwSettings::RM_FLEXIPORT_DISABLED); + } + } +} + +void ConfigRevoHWWidget::openHelp() +{ + QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/x/GgDBAQ", QUrl::StrictMode) ); +} diff --git a/ground/openpilotgcs/src/plugins/config/config_pro_hw_widget.h b/ground/openpilotgcs/src/plugins/config/configrevohwwidget.h similarity index 64% rename from ground/openpilotgcs/src/plugins/config/config_pro_hw_widget.h rename to ground/openpilotgcs/src/plugins/config/configrevohwwidget.h index 021e19aaf..7e6ed51f4 100644 --- a/ground/openpilotgcs/src/plugins/config/config_pro_hw_widget.h +++ b/ground/openpilotgcs/src/plugins/config/configrevohwwidget.h @@ -1,13 +1,13 @@ /** ****************************************************************************** * - * @file configtelemetrytwidget.h + * @file configrevohwwidget.h * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @addtogroup GCSPlugins GCS Plugins * @{ * @addtogroup ConfigPlugin Config Plugin * @{ - * @brief Telemetry configuration panel + * @brief Revolution hardware configuration panel *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -24,10 +24,10 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef CONFIGPROHWWIDGET_H -#define CONFIGPROHWWIDGET_H +#ifndef CONFIGREVOHWWIDGET_H +#define CONFIGREVOHWWIDGET_H -#include "ui_pro_hw_settings.h" +#include "ui_configrevohwwidget.h" #include "../uavobjectwidgetutils/configtaskwidget.h" #include "extensionsystem/pluginmanager.h" #include "uavobjectmanager.h" @@ -36,20 +36,30 @@ #include -class ConfigProHWWidget: public ConfigTaskWidget +class ConfigRevoHWWidget: public ConfigTaskWidget { Q_OBJECT public: - ConfigProHWWidget(QWidget *parent = 0); - ~ConfigProHWWidget(); + ConfigRevoHWWidget(QWidget *parent = 0); + ~ConfigRevoHWWidget(); private: - Ui_PRO_HW_Widget *m_telemetry; + Ui_RevoHWWidget *m_ui; + void setupCustomCombos(); + +protected slots: + void refreshWidgetsValues(UAVObject * obj = NULL); + void updateObjectsFromWidgets(); private slots: - virtual void refreshValues(); + void usbVCPPortChanged(int index); + void usbHIDPortChanged(int index); + void flexiPortChanged(int index); + void mainPortChanged(int index); + void modemPortChanged(int index); + void openHelp(); }; -#endif // CONFIGPROHWWIDGET_H +#endif // CONFIGREVOHWWIDGET_H diff --git a/ground/openpilotgcs/src/plugins/config/configrevohwwidget.ui b/ground/openpilotgcs/src/plugins/config/configrevohwwidget.ui new file mode 100644 index 000000000..199d2e817 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/config/configrevohwwidget.ui @@ -0,0 +1,865 @@ + + + RevoHWWidget + + + + 0 + 0 + 834 + 742 + + + + Form + + + + + + 0 + + + + HW settings + + + + 0 + + + + + + + + + + 255 + 255 + 255 + + + + + + + 232 + 232 + 232 + + + + + + + + + 255 + 255 + 255 + + + + + + + 232 + 232 + 232 + + + + + + + + + 232 + 232 + 232 + + + + + + + 232 + 232 + 232 + + + + + + + + border-color: rgb(255, 0, 0); + + + QFrame::NoFrame + + + QFrame::Plain + + + true + + + + + 0 + 0 + 810 + 665 + + + + + 12 + + + + + + + + 0 + 0 + + + + USB VCP Function + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + Speed + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + false + + + + + + + + 0 + 0 + + + + Speed + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + + + + + + + + 0 + 0 + + + + USB HID Function + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + + + + true + + + + + + + Main Port + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 50 + 10 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 120 + 10 + + + + + + + + + 0 + 0 + + + + + 350 + 350 + + + + + + + :/configgadget/images/revolution_top.png + + + false + + + Qt::AlignCenter + + + Qt::NoTextInteraction + + + + + + + + + + + 0 + 0 + + + + Sonar Port + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + + + + 0 + + + + + true + + + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 120 + 10 + + + + + + + + Flexi Port + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + 0 + + + + + true + + + + + + + + + + + + + + + + + + Radio + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + Speed + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 120 + 10 + + + + + + + + + 0 + 0 + + + + Receiver Port + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 25 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 120 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 120 + 10 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 120 + 10 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 13 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 13 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 13 + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + 75 + true + + + + Changes on this page only take effect after board reset or power cycle + + + Qt::AlignCenter + + + true + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + 4 + + + + + Qt::Horizontal + + + + 369 + 20 + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + Takes you to the wiki page + + + + + + + :/core/images/helpicon.svg:/core/images/helpicon.svg + + + + 25 + 25 + + + + true + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + 255 + 255 + 255 + + + + + + + 232 + 232 + 232 + + + + + + + + + 255 + 255 + 255 + + + + + + + 232 + 232 + 232 + + + + + + + + + 232 + 232 + 232 + + + + + + + 232 + 232 + 232 + + + + + + + + Send to OpenPilot but don't write in SD. +Beware of not locking yourself out! + + + false + + + + + + Apply + + + + 16 + 16 + + + + false + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Applies and Saves all settings to SD. +Beware of not locking yourself out! + + + false + + + + + + Save + + + + + + + + + + + + + diff --git a/ground/openpilotgcs/src/plugins/config/images/revolution_top.png b/ground/openpilotgcs/src/plugins/config/images/revolution_top.png new file mode 100644 index 000000000..a98e7e377 Binary files /dev/null and b/ground/openpilotgcs/src/plugins/config/images/revolution_top.png differ diff --git a/ground/openpilotgcs/src/plugins/config/pro_hw_settings.ui b/ground/openpilotgcs/src/plugins/config/pro_hw_settings.ui deleted file mode 100644 index 4c782357c..000000000 --- a/ground/openpilotgcs/src/plugins/config/pro_hw_settings.ui +++ /dev/null @@ -1,126 +0,0 @@ - - - PRO_HW_Widget - - - - 0 - 0 - 505 - 389 - - - - Form - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - <!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:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;"> -<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:'Sans'; font-size:10pt;">Set the serial speed of your onboard telemetry modem here. It is the speed between the OpenPilot board and the onboard modem, and could be different from the radio link speed.</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:'Sans'; font-size:10pt;"><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-family:'Sans'; font-size:10pt;">Beware of not locking yourself out! You should only modify this setting when the OpenPilot board is connected through the USB port.</span></p></body></html> - - - - - - - - - - 11 - 75 - true - - - - Telemetry speed: - - - - - - - Select the speed here. - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - 4 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Send to OpenPilot but don't write in SD. -Beware of not locking yourself out! - - - Apply - - - - - - - Applies and Saves all settings to SD. -Beware of not locking yourself out! - - - Save - - - - - - - - - - - - - diff --git a/ground/openpilotgcs/src/plugins/coreplugin/CREDITS.html b/ground/openpilotgcs/src/plugins/coreplugin/CREDITS.html index 341e288f6..a71f7570a 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/CREDITS.html +++ b/ground/openpilotgcs/src/plugins/coreplugin/CREDITS.html @@ -1,8 +1,12 @@ -

This is a credits file of people that are or have been key contributors to the OpenPilot project. -Without the work of the people in this file OpenPilot would not be what it is today.

+ + +

This is a credits file of people that are or 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.

-

It is sorted alphabetically by name

+

This list is sorted alphabetically by name

Connor Abbott
 David Ankers
@@ -77,5 +81,5 @@ Mat Wellington
 Kendal Wells
 Dmitriy Zaitsev
 
- + diff --git a/ground/openpilotgcs/src/plugins/coreplugin/authorsdialog.cpp b/ground/openpilotgcs/src/plugins/coreplugin/authorsdialog.cpp index a6cb6b8c5..0978a4638 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/authorsdialog.cpp +++ b/ground/openpilotgcs/src/plugins/coreplugin/authorsdialog.cpp @@ -28,6 +28,8 @@ #include "authorsdialog.h" +// autogenerated version info string +#include "../../../../../build/ground/openpilotgcs/gcsversioninfo.h" #include "coreconstants.h" #include "icore.h" @@ -42,6 +44,11 @@ #include #include #include + +#include +#include +#include +#include using namespace Core; using namespace Core::Internal; @@ -52,45 +59,75 @@ AuthorsDialog::AuthorsDialog(QWidget *parent) { // We need to set the window icon explicitly here since for some reason the // application icon isn't used when the size of the dialog is fixed (at least not on X11/GNOME) + setWindowIcon(QIcon(":/core/images/openpilot_logo_32.png")); - - setWindowTitle(tr("About OpenPilot Authors")); + setWindowTitle(tr("About OpenPilot")); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - QGridLayout *layout = new QGridLayout(this); - layout->setSizeConstraint(QLayout::SetFixedSize); + // This loads a QML doc containing a Tabbed view + QDeclarativeView *view = new QDeclarativeView(this); + view->setSource(QUrl("qrc:/core/qml/AboutDialog.qml")); - QString version = QLatin1String(GCS_VERSION_LONG); - version += QDate(2007, 25, 10).toString(Qt::SystemLocaleDate); - QString ideRev; + + QString version = QLatin1String(GCS_VERSION_LONG); + version += QDate(2007, 25, 10).toString(Qt::SystemLocaleDate); + + QString ideRev; #ifdef GCS_REVISION - //: This gets conditionally inserted as argument %8 into the description string. - ideRev = tr("From revision %1
").arg(QString::fromLatin1(GCS_REVISION_STR).left(10)); + //: This gets conditionally inserted as argument %8 into the description string. + ideRev = tr("From revision %1
").arg(QString::fromLatin1(GCS_REVISION_STR).left(10)); #endif - const QString description = tr( - "

The OpenPilot Project

" - "Proudly brought to you by this fine team:
" - ); - - QLabel *copyRightLabel = new QLabel(description); - copyRightLabel->setWordWrap(true); - copyRightLabel->setOpenExternalLinks(true); - copyRightLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - - QTextBrowser *creditsArea = new QTextBrowser(this); - creditsArea->setSource(QUrl("qrc:core/CREDITS.html")); - - QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); - QPushButton *closeButton = buttonBox->button(QDialogButtonBox::Close); - QTC_ASSERT(closeButton, /**/); - buttonBox->addButton(closeButton, QDialogButtonBox::ButtonRole(QDialogButtonBox::RejectRole | QDialogButtonBox::AcceptRole)); - connect(buttonBox , SIGNAL(rejected()), this, SLOT(reject())); - - QLabel *logoLabel = new QLabel; - logoLabel->setPixmap(QPixmap(QLatin1String(":/core/images/openpilot_logo_128.png"))); - layout->addWidget(logoLabel , 0, 0, 1, 1); - layout->addWidget(copyRightLabel, 0, 1, 2, 4); - layout->addWidget(creditsArea, 3, 0, 2, 5); - layout->addWidget(buttonBox, 6, 0, 1, 5); + #ifdef UAVO_HASH + //: This gets conditionally inserted as argument %11 into the description string. + QByteArray uavoHashArray; + QString uavoHash = QString::fromLatin1(Core::Constants::UAVOSHA1_STR); + uavoHash.chop(2); + uavoHash.remove(0, 2); + uavoHash = uavoHash.trimmed(); + bool ok; + foreach(QString str, uavoHash.split(",")) { + uavoHashArray.append(str.toInt(&ok, 16)); + } + QString gcsUavoHashStr; + foreach(char i, uavoHashArray) { + gcsUavoHashStr.append(QString::number(i, 16).right(2)); + } + QString uavoHashStr = gcsUavoHashStr; +#else + QString uavoHashStr = "N/A"; +#endif + const QString description = tr( + "

OpenPilot Ground Control Station

" + "GCS Revision: %1
" + "UAVO Hash: %2
" + "
" + "Built from %3
" + "Built on %4 at %5
" + "Based on Qt %6 (%7 bit)
" + "
" + "© %8, 2010-%9. All rights reserved.
" + "
" + "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.
" + "
" + "The program is provided AS IS with NO WARRANTY OF ANY KIND, " + "INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A " + "PARTICULAR PURPOSE.
" + ).arg( + QString::fromLatin1(GCS_REVISION_STR).left(60), // %1 + uavoHashStr, // %2 + QLatin1String(GCS_ORIGIN_STR), // $3 + QLatin1String(__DATE__), // %4 + QLatin1String(__TIME__), // %5 + QLatin1String(QT_VERSION_STR), // %6 + QString::number(QSysInfo::WordSize), // %7 + QLatin1String(GCS_AUTHOR), // %8 + QLatin1String(GCS_YEAR_STR) // %9 + ); + // Expose the version description to the QML doc + view->rootContext()->setContextProperty("version", description); + } diff --git a/ground/openpilotgcs/src/plugins/coreplugin/core.qrc b/ground/openpilotgcs/src/plugins/coreplugin/core.qrc index 74579c457..85ca549e6 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/core.qrc +++ b/ground/openpilotgcs/src/plugins/coreplugin/core.qrc @@ -1,66 +1,70 @@ - images/openpilot_logo_256.png - images/openpilot_logo_128.png - images/openpilot_logo_64.png - images/openpilot_logo_32.png - images/clean_pane_small.png - images/clear.png - images/closebutton.png - images/dir.png - images/editcopy.png - images/editcut.png - images/editpaste.png - images/empty14.png - images/filenew.png - images/fileopen.png - images/filesave.png - images/find.png - images/findnext.png - images/inputfield.png - images/inputfield_disabled.png - images/linkicon.png - images/locked.png - images/magnifier.png - images/minus.png - images/next.png - images/panel_button.png - images/panel_button_checked.png - images/panel_button_checked_hover.png - images/panel_button_hover.png - images/panel_button_pressed.png - images/plus.png - images/prev.png - images/pushbutton.png - images/pushbutton_hover.png - images/pushbutton_pressed.png - images/redo.png - images/replace.png - images/reset.png - images/sidebaricon.png - images/splitbutton_horizontal.png - images/statusbar.png - images/undo.png - images/unknownfile.png - images/unlocked.png - images/extension.png - images/darkclosebutton.png - images/pluginicon.png - images/exiticon.png - images/optionsicon.png - images/helpicon.png - images/openpiloticon.png - CREDITS.html - images/ah.png - images/config.png - images/flight.png - images/home.png - images/joystick.png - images/scopes.png - images/world.png - images/cog.png - images/helpicon.svg - images/cpu.png - images/tx-rx.svg + images/openpilot_logo_256.png + images/openpilot_logo_128.png + images/openpilot_logo_64.png + images/openpilot_logo_32.png + images/clean_pane_small.png + images/clear.png + images/closebutton.png + images/dir.png + images/editcopy.png + images/editcut.png + images/editpaste.png + images/empty14.png + images/filenew.png + images/fileopen.png + images/filesave.png + images/find.png + images/findnext.png + images/inputfield.png + images/inputfield_disabled.png + images/linkicon.png + images/locked.png + images/magnifier.png + images/minus.png + images/next.png + images/panel_button.png + images/panel_button_checked.png + images/panel_button_checked_hover.png + images/panel_button_hover.png + images/panel_button_pressed.png + images/plus.png + images/prev.png + images/pushbutton.png + images/pushbutton_hover.png + images/pushbutton_pressed.png + images/redo.png + images/replace.png + images/reset.png + images/sidebaricon.png + images/splitbutton_horizontal.png + images/statusbar.png + images/undo.png + images/unknownfile.png + images/unlocked.png + images/extension.png + images/darkclosebutton.png + images/pluginicon.png + images/exiticon.png + images/optionsicon.png + images/helpicon.png + images/openpiloticon.png + CREDITS.html + images/ah.png + images/config.png + images/flight.png + images/home.png + images/joystick.png + images/scopes.png + images/world.png + images/cog.png + images/helpicon.svg + images/cpu.png + images/tx-rx.svg + qml/images/tab.png + qml/AboutDialog.qml + qml/FlickableWebView.qml + qml/TabWidget.qml diff --git a/ground/openpilotgcs/src/plugins/coreplugin/coreplugin.pro b/ground/openpilotgcs/src/plugins/coreplugin/coreplugin.pro index 17cbeae2b..90ded4b4f 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/coreplugin.pro +++ b/ground/openpilotgcs/src/plugins/coreplugin/coreplugin.pro @@ -1,11 +1,12 @@ TEMPLATE = lib TARGET = Core DEFINES += CORE_LIBRARY -QT += xml \ +QT += declarative \ + xml \ network \ script \ svg \ - sql + sql include(../../openpilotgcsplugin.pri) include(../../libs/utils/utils.pri) include(../../shared/scriptwrapper/scriptwrapper.pri) diff --git a/ground/openpilotgcs/src/plugins/coreplugin/coreplugin.pro.user b/ground/openpilotgcs/src/plugins/coreplugin/coreplugin.pro.user new file mode 100644 index 000000000..0bdc53354 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/coreplugin/coreplugin.pro.user @@ -0,0 +1,564 @@ + + + + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + System + false + 4 + true + 1 + true + 0 + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Qt4ProjectManager.Target.DesktopTarget + 0 + 0 + 0 + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Qt 4.8.3 in PATH (System) Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /Users/kevin/Documents/Source/OpenPilot-Private/ground/openpilotgcs/src/plugins/coreplugin-build-desktop-Qt_4_8_3_in_PATH__System__Debug + 7 + true + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Qt 4.8.3 in PATH (System) Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /Users/kevin/Documents/Source/OpenPilot-Private/ground/openpilotgcs/src/plugins/coreplugin-build-desktop-Qt_4_8_3_in_PATH__System__Release + 7 + true + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Desktop Qt 4.8.1 for GCC (Qt SDK) Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /Users/kevin/Documents/Source/OpenPilot-Private/ground/openpilotgcs/src/plugins/coreplugin-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug + 6 + true + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Desktop Qt 4.8.1 for GCC (Qt SDK) Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /Users/kevin/Documents/Source/OpenPilot-Private/ground/openpilotgcs/src/plugins/coreplugin-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Release + 6 + true + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Desktop Qt 4.8.0 for GCC (Qt SDK) Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /Users/kevin/Documents/Source/OpenPilot-Private/ground/openpilotgcs/src/plugins/coreplugin-build-desktop-Desktop_Qt_4_8_0_for_GCC__Qt_SDK__Debug + 5 + true + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Desktop Qt 4.8.0 for GCC (Qt SDK) Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /Users/kevin/Documents/Source/OpenPilot-Private/ground/openpilotgcs/src/plugins/coreplugin-build-desktop-Desktop_Qt_4_8_0_for_GCC__Qt_SDK__Release + 5 + true + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Desktop Qt 4.7.4 for GCC (Qt SDK) Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /Users/kevin/Documents/Source/OpenPilot-Private/ground/openpilotgcs/src/plugins/coreplugin-build-desktop-Desktop_Qt_4_7_4_for_GCC__Qt_SDK__Debug + 3 + true + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-64bit./usr/bin/gdb + + + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Desktop Qt 4.7.4 for GCC (Qt SDK) Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /Users/kevin/Documents/Source/OpenPilot-Private/ground/openpilotgcs/src/plugins/coreplugin-build-desktop-Desktop_Qt_4_7_4_for_GCC__Qt_SDK__Release + 3 + true + + 8 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + No deployment + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + + + false + false + false + false + false + false + false + false + true + true + 0.01 + 0.01 + 10 + 10 + true + true + 25 + 25 + + + true + true + valgrind + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 2 + + false + + %{buildDir} + Custom Executable + + ProjectExplorer.CustomExecutableRunConfiguration + 3768 + true + false + false + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.EnvironmentId + {51e7adba-6ef9-490c-b046-228d3817bea8} + + + ProjectExplorer.Project.Updater.FileVersion + 10 + + diff --git a/ground/openpilotgcs/src/plugins/coreplugin/mainwindow.cpp b/ground/openpilotgcs/src/plugins/coreplugin/mainwindow.cpp index 000156d70..f53769b90 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/mainwindow.cpp +++ b/ground/openpilotgcs/src/plugins/coreplugin/mainwindow.cpp @@ -91,6 +91,7 @@ using namespace Core; using namespace Core::Internal; static const char *uriListMimeFormatC = "text/uri-list"; +static const char *DEFAULT_CONFIG_FILENAME = "OpenPilotGCS.xml"; enum { debugMainWindow = 0 }; @@ -267,7 +268,6 @@ void MainWindow::modeChanged(Core::IMode */*mode*/) void MainWindow::extensionsInitialized() { QSettings *qs = m_settings; - QSettings *settings; QString commandLine; if ( ! qs->allKeys().count() ) { foreach(QString str, qApp->arguments()) { @@ -288,28 +288,31 @@ void MainWindow::extensionsInitialized() #endif directory.cd("default_configurations"); - qDebug() << "Looking for default config files in: " + directory.absolutePath(); - bool showDialog = true; + qDebug() << "Looking for configuration files in:" << directory.absolutePath(); + QString filename; - if(!commandLine.isEmpty()) { - if(QFile::exists(directory.absolutePath() + QDir::separator()+commandLine)) { - filename = directory.absolutePath() + QDir::separator()+commandLine; - qDebug() << "Load configuration from command line"; - settings = new QSettings(filename, XmlConfig::XmlSettingsFormat); - showDialog = false; - } + if(!commandLine.isEmpty() && QFile::exists(directory.absolutePath() + QDir::separator() + commandLine)) { + filename = directory.absolutePath() + QDir::separator() + commandLine; + qDebug() << "Configuration file" << filename << "specified on command line will be loaded."; } - if(showDialog) { + else if(QFile::exists(directory.absolutePath() + QDir::separator() + DEFAULT_CONFIG_FILENAME)) { + filename = directory.absolutePath() + QDir::separator() + DEFAULT_CONFIG_FILENAME; + qDebug() << "Default configuration file" << filename << "will be loaded."; + } + else { + qDebug() << "Default configuration file " << directory.absolutePath() << QDir::separator() << DEFAULT_CONFIG_FILENAME << "was not found."; importSettings *dialog = new importSettings(this); dialog->loadFiles(directory.absolutePath()); dialog->exec(); filename = dialog->choosenConfig(); - settings = new QSettings(filename, XmlConfig::XmlSettingsFormat); delete dialog; + qDebug() << "Configuration file" << filename << "was selected and will be loaded."; } - qs = settings; - qDebug() << "Load default config from resource " << filename; + + qs = new QSettings(filename, XmlConfig::XmlSettingsFormat); + qDebug() << "Configuration file" << filename << "was loaded."; } + qs->beginGroup("General"); m_config_description=qs->value("Description", "none").toString(); m_config_details=qs->value("Details", "none").toString(); @@ -795,15 +798,13 @@ void MainWindow::registerDefaultActions() // About GCS Action #ifdef Q_WS_MAC - tmpaction = new QAction(QIcon(Constants::ICON_OPENPILOT), tr("About &OpenPilot GCS"), this); // it's convention not to add dots to the about menu + #else - tmpaction = new QAction(QIcon(Constants::ICON_OPENPILOT), tr("About &OpenPilot GCS..."), this); + #endif - cmd = am->registerAction(tmpaction, Constants::ABOUT_OPENPILOTGCS, m_globalContext); - mhelp->addAction(cmd, Constants::G_HELP_ABOUT); - tmpaction->setEnabled(true); + #ifdef Q_WS_MAC - cmd->action()->setMenuRole(QAction::ApplicationSpecificRole); + #endif connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutOpenPilotGCS())); @@ -818,7 +819,7 @@ void MainWindow::registerDefaultActions() connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutPlugins())); //Credits Action - tmpaction = new QAction(QIcon(Constants::ICON_PLUGIN), tr("About &Authors..."), this); + tmpaction = new QAction(QIcon(Constants::ICON_PLUGIN), tr("About &OpenPilot..."), this); cmd = am->registerAction(tmpaction, Constants::ABOUT_AUTHORS, m_globalContext); mhelp->addAction(cmd, Constants::G_HELP_ABOUT); tmpaction->setEnabled(true); diff --git a/ground/openpilotgcs/src/plugins/coreplugin/qml/AboutDialog.qml b/ground/openpilotgcs/src/plugins/coreplugin/qml/AboutDialog.qml new file mode 100644 index 000000000..e9190b082 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/coreplugin/qml/AboutDialog.qml @@ -0,0 +1,110 @@ + /**************************************************************************** + ** + ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + ** All rights reserved. + ** Contact: Nokia Corporation (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor + ** the names of its contributors may be used to endorse or promote + ** products derived from this software without specific prior written + ** permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + + import QtQuick 1.1 + import QtWebKit 1.0 + + // This is a tabbed pane element. Add a nested Rectangle to add a tab. + TabWidget { + 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 is a stub for the Plugins. + // Rectangle { + // property string title: "Plugins" + // anchors.fill: parent + // color: "#e3e3e3" + // + // Rectangle { + // anchors.fill: parent; anchors.margins: 20 + // color: "#7fff7f" + // Text { + // width: parent.width - 20 + // anchors.centerIn: parent; horizontalAlignment: Qt.AlignHCenter + // font.pixelSize: 20 + // wrapMode: Text.WordWrap + // } + // } + // } + // 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" + FlickableWebView { + id: webView + z: 0 + url: "../CREDITS.html" + anchors { top: parent.top; left: parent.left; right: parent.right; bottom: parent.bottom } + } + } + } + } diff --git a/ground/openpilotgcs/src/plugins/coreplugin/qml/FlickableWebView.qml b/ground/openpilotgcs/src/plugins/coreplugin/qml/FlickableWebView.qml new file mode 100644 index 000000000..3043ce88a --- /dev/null +++ b/ground/openpilotgcs/src/plugins/coreplugin/qml/FlickableWebView.qml @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.0 +import QtWebKit 1.0 + +Flickable { + property alias title: webView.title + property alias icon: webView.icon + property alias progress: webView.progress + property alias url: webView.url + property alias back: webView.back + property alias stop: webView.stop + property alias reload: webView.reload + property alias forward: webView.forward + + id: flickable + width: parent.width + contentWidth: Math.max(parent.width,webView.width) + contentHeight: Math.max(parent.height,webView.height) + // anchors.top: headerSpace.bottom + anchors.bottom: parent.top + anchors.left: parent.left + anchors.right: parent.right + pressDelay: 200 + clip: true + + onWidthChanged : { + // Expand (but not above 1:1) if otherwise would be smaller that available width. + if (width > webView.width*webView.contentsScale && webView.contentsScale < 1.0) + webView.contentsScale = width / webView.width * webView.contentsScale; + } + + WebView { + id: webView + transformOrigin: Item.TopLeft + + function fixUrl(url) + { + if (url == "") return url + if (url[0] == "/") return "file://"+url + if (url.indexOf(":")<0) { + if (url.indexOf(".")<0 || url.indexOf(" ")>=0) { + // Fall back to a search engine; hard-code Wikipedia + return "http://en.wikipedia.org/w/index.php?search="+url + } else { + return "http://"+url + } + } + return url + } + + url: fixUrl(webBrowser.urlString) + smooth: false // We don't want smooth scaling, since we only scale during (fast) transitions + focus: true + + onAlert: console.log(message) + + function doZoom(zoom,centerX,centerY) + { + if (centerX) { + var sc = zoom*contentsScale; + scaleAnim.to = sc; + flickVX.from = flickable.contentX + flickVX.to = Math.max(0,Math.min(centerX-flickable.width/2,webView.width*sc-flickable.width)) + finalX.value = flickVX.to + flickVY.from = flickable.contentY + flickVY.to = Math.max(0,Math.min(centerY-flickable.height/2,webView.height*sc-flickable.height)) + finalY.value = flickVY.to + quickZoom.start() + } + } + + Keys.onLeftPressed: webView.contentsScale -= 0.1 + Keys.onRightPressed: webView.contentsScale += 0.1 + + preferredWidth: flickable.width + preferredHeight: flickable.height + contentsScale: 1 + onContentsSizeChanged: { + // zoom out + contentsScale = Math.min(1,flickable.width / contentsSize.width) + } + onUrlChanged: { + // got to topleft + flickable.contentX = 0 + flickable.contentY = 0 + // if (url != null) { header.editUrl = url.toString(); } + } + onDoubleClick: { + if (!heuristicZoom(clickX,clickY,2.5)) { + var zf = flickable.width / contentsSize.width + if (zf >= contentsScale) + zf = 2.0*contentsScale // zoom in (else zooming out) + doZoom(zf,clickX*zf,clickY*zf) + } + } + + SequentialAnimation { + id: quickZoom + + PropertyAction { + target: webView + property: "renderingEnabled" + value: false + } + ParallelAnimation { + NumberAnimation { + id: scaleAnim + target: webView + property: "contentsScale" + // the to property is set before calling + easing.type: Easing.Linear + duration: 200 + } + NumberAnimation { + id: flickVX + target: flickable + property: "contentX" + easing.type: Easing.Linear + duration: 200 + from: 0 // set before calling + to: 0 // set before calling + } + NumberAnimation { + id: flickVY + target: flickable + property: "contentY" + easing.type: Easing.Linear + duration: 200 + from: 0 // set before calling + to: 0 // set before calling + } + } + // Have to set the contentXY, since the above 2 + // size changes may have started a correction if + // contentsScale < 1.0. + PropertyAction { + id: finalX + target: flickable + property: "contentX" + value: 0 // set before calling + } + PropertyAction { + id: finalY + target: flickable + property: "contentY" + value: 0 // set before calling + } + PropertyAction { + target: webView + property: "renderingEnabled" + value: true + } + } + onZoomTo: doZoom(zoom,centerX,centerY) + } +} diff --git a/ground/openpilotgcs/src/plugins/coreplugin/qml/TabWidget.qml b/ground/openpilotgcs/src/plugins/coreplugin/qml/TabWidget.qml new file mode 100644 index 000000000..b6ce6bd41 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/coreplugin/qml/TabWidget.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.1 + +Item { + id: tabWidget + + // Setting the default property to stack.children means any child items + // of the TabWidget are actually added to the 'stack' item's children. + // See the "Property Binding" + // documentation for details on default properties. + default property alias content: stack.children + + property int current: 0 + + onCurrentChanged: setOpacities() + Component.onCompleted: setOpacities() + + function setOpacities() { + for (var i = 0; i < stack.children.length; ++i) { + stack.children[i].opacity = (i == current ? 1 : 0) + } + } + + Row { + id: header + + Repeater { + model: stack.children.length + delegate: Rectangle { + width: tabWidget.width / stack.children.length; height: 36 + + Rectangle { + width: parent.width; height: 1 + anchors { bottom: parent.bottom; bottomMargin: 1 } + color: "#acb2c2" + } + BorderImage { + anchors { fill: parent; leftMargin: 2; topMargin: 5; rightMargin: 1 } + border { left: 7; right: 7 } + source: "images/tab.png" + visible: tabWidget.current == index + } + Text { + horizontalAlignment: Qt.AlignHCenter; verticalAlignment: Qt.AlignVCenter + anchors.fill: parent + text: stack.children[index].title + elide: Text.ElideRight + font.bold: tabWidget.current == index + } + MouseArea { + anchors.fill: parent + onClicked: tabWidget.current = index + } + } + } + } + + Item { + id: stack + width: tabWidget.width + anchors.top: header.bottom; anchors.bottom: tabWidget.bottom + } +} \ No newline at end of file diff --git a/ground/openpilotgcs/src/plugins/coreplugin/qml/images/tab.png b/ground/openpilotgcs/src/plugins/coreplugin/qml/images/tab.png new file mode 100644 index 000000000..ad8021605 Binary files /dev/null and b/ground/openpilotgcs/src/plugins/coreplugin/qml/images/tab.png differ diff --git a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetdecorator.cpp b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetdecorator.cpp index fd6d1164e..78a98a210 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetdecorator.cpp +++ b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetdecorator.cpp @@ -45,8 +45,6 @@ UAVGadgetDecorator::UAVGadgetDecorator(IUAVGadget *gadget, QListaddItem(config->name()); connect(m_toolbar, SIGNAL(activated(int)), this, SLOT(loadConfiguration(int))); - if (m_configurations->count() > 0) - loadConfiguration(0); updateToolbar(); } @@ -57,7 +55,7 @@ UAVGadgetDecorator::~UAVGadgetDecorator() } void UAVGadgetDecorator::loadConfiguration(int index) { - IUAVGadgetConfiguration* config = m_configurations->at(index); + IUAVGadgetConfiguration *config = m_configurations->at(index); loadConfiguration(config); } @@ -70,13 +68,13 @@ void UAVGadgetDecorator::loadConfiguration(IUAVGadgetConfiguration *config) } -void UAVGadgetDecorator::configurationChanged(IUAVGadgetConfiguration* config) +void UAVGadgetDecorator::configurationChanged(IUAVGadgetConfiguration *config) { if (config == m_activeConfiguration) loadConfiguration(config); } -void UAVGadgetDecorator::configurationAdded(IUAVGadgetConfiguration* config) +void UAVGadgetDecorator::configurationAdded(IUAVGadgetConfiguration *config) { if (config->classId() != classId()) return; @@ -85,7 +83,7 @@ void UAVGadgetDecorator::configurationAdded(IUAVGadgetConfiguration* config) updateToolbar(); } -void UAVGadgetDecorator::configurationToBeDeleted(IUAVGadgetConfiguration* config) +void UAVGadgetDecorator::configurationToBeDeleted(IUAVGadgetConfiguration *config) { if (config->classId() != classId()) return; @@ -97,7 +95,7 @@ void UAVGadgetDecorator::configurationToBeDeleted(IUAVGadgetConfiguration* confi updateToolbar(); } -void UAVGadgetDecorator::configurationNameChanged(IUAVGadgetConfiguration* config, QString oldName, QString newName) +void UAVGadgetDecorator::configurationNameChanged(IUAVGadgetConfiguration *config, QString oldName, QString newName) { if (config->classId() != classId()) return; @@ -112,20 +110,21 @@ void UAVGadgetDecorator::updateToolbar() m_toolbar->setEnabled(m_toolbar->count() > 1); } -void UAVGadgetDecorator::saveState(QSettings* qSettings) +void UAVGadgetDecorator::saveState(QSettings *qSettings) { if (m_activeConfiguration) { - qSettings->setValue("activeConfiguration",m_activeConfiguration->name()); + qSettings->setValue("activeConfiguration", m_activeConfiguration->name()); } } -void UAVGadgetDecorator::restoreState(QSettings* qSetting) +void UAVGadgetDecorator::restoreState(QSettings *qSettings) { - QString configName = qSetting->value("activeConfiguration").toString(); + QString configName = qSettings->value("activeConfiguration").toString(); foreach (IUAVGadgetConfiguration *config, *m_configurations) { if (config->name() == configName) { m_activeConfiguration = config; loadConfiguration(config); + break; } } } diff --git a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.cpp b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.cpp index 3fa7eaf9e..a20612c59 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.cpp +++ b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.cpp @@ -262,13 +262,17 @@ void UAVGadgetInstanceManager::createOptionsPages() } -IUAVGadget *UAVGadgetInstanceManager::createGadget(QString classId, QWidget *parent) +IUAVGadget *UAVGadgetInstanceManager::createGadget(QString classId, QWidget *parent, bool loadDefaultConfiguration) { IUAVGadgetFactory *f = factory(classId); if (f) { QList *configs = configurations(classId); IUAVGadget *g = f->createGadget(parent); - IUAVGadget *gadget = new UAVGadgetDecorator(g, configs); + UAVGadgetDecorator *gadget = new UAVGadgetDecorator(g, configs); + if ((loadDefaultConfiguration && configs && configs->count()) > 0) { + gadget->loadConfiguration(configs->at(0)); + } + m_gadgetInstances.append(gadget); connect(this, SIGNAL(configurationAdded(IUAVGadgetConfiguration*)), gadget, SLOT(configurationAdded(IUAVGadgetConfiguration*))); connect(this, SIGNAL(configurationChanged(IUAVGadgetConfiguration*)), gadget, SLOT(configurationChanged(IUAVGadgetConfiguration*))); diff --git a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.h b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.h index fab30f284..a67953fc1 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.h +++ b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetinstancemanager.h @@ -61,7 +61,7 @@ public: ~UAVGadgetInstanceManager(); void readSettings(QSettings *qs); void saveSettings(QSettings *qs); - IUAVGadget *createGadget(QString classId, QWidget *parent); + IUAVGadget *createGadget(QString classId, QWidget *parent, bool loadDefaultConfiguration = true); void removeGadget(IUAVGadget *gadget); void removeAllGadgets(); bool canDeleteConfiguration(IUAVGadgetConfiguration *config); diff --git a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/splitterorview.cpp b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/splitterorview.cpp index 183ffa185..2a3a02f64 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/splitterorview.cpp +++ b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/splitterorview.cpp @@ -347,11 +347,7 @@ void SplitterOrView::saveState(QSettings* qSettings) const { static_cast(m_splitter->widget(1))->saveState(qSettings); qSettings->endGroup(); } else if (gadget()) { - qSettings->setValue("type", "uavGadget"); - qSettings->setValue("classId", gadget()->classId()); - qSettings->beginGroup("gadget"); - gadget()->saveState(qSettings); - qSettings->endGroup(); + m_view->saveState(qSettings); } } @@ -374,13 +370,6 @@ void SplitterOrView::restoreState(QSettings* qSettings) static_cast(m_splitter->widget(1))->restoreState(qSettings); qSettings->endGroup(); } else if (mode == "uavGadget") { - QString classId = qSettings->value("classId").toString(); - int index = m_view->indexOfClassId(classId); - m_view->listSelectionActivated(index); - if(qSettings->childGroups().contains("gadget")) { - qSettings->beginGroup("gadget"); - gadget()->restoreState(qSettings); - qSettings->endGroup(); - } + m_view->restoreState(qSettings); } } diff --git a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.cpp b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.cpp index 13b2b3062..5a380c576 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.cpp +++ b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.cpp @@ -230,14 +230,17 @@ void UAVGadgetView::updateToolBar() void UAVGadgetView::listSelectionActivated(int index) { - if (index < 0) // this could happen when called from SplitterOrView::restoreState() + if (index < 0 || index >= m_uavGadgetList->count()) index = m_defaultIndex; + QString classId = m_uavGadgetList->itemData(index).toString(); if (m_uavGadget && (m_uavGadget->classId() == classId)) return; + UAVGadgetInstanceManager *im = ICore::instance()->uavGadgetInstanceManager(); - IUAVGadget *gadgetToRemove = m_uavGadget; IUAVGadget *gadget = im->createGadget(classId, this); + + IUAVGadget *gadgetToRemove = m_uavGadget; setGadget(gadget); m_uavGadgetManager->setCurrentGadget(gadget); im->removeGadget(gadgetToRemove); @@ -252,3 +255,39 @@ void UAVGadgetView::currentGadgetChanged(IUAVGadget *gadget) { m_activeLabel->setVisible(m_uavGadget == gadget); } + +void UAVGadgetView::saveState(QSettings* qSettings) +{ + qSettings->setValue("type", "uavGadget"); + qSettings->setValue("classId", gadget()->classId()); + qSettings->beginGroup("gadget"); + gadget()->saveState(qSettings); + qSettings->endGroup(); +} + +void UAVGadgetView::restoreState(QSettings* qSettings) +{ + QString classId = qSettings->value("classId").toString(); + int index = indexOfClassId(classId); + if (index < 0) { + index = m_defaultIndex; + } + classId = m_uavGadgetList->itemData(index).toString(); + + IUAVGadget *newGadget; + UAVGadgetInstanceManager *im = ICore::instance()->uavGadgetInstanceManager(); + if(qSettings->childGroups().contains("gadget")) { + newGadget = im->createGadget(classId, this, false); + qSettings->beginGroup("gadget"); + newGadget->restoreState(qSettings); + qSettings->endGroup(); + } + else { + newGadget = im->createGadget(classId, this); + } + + IUAVGadget *gadgetToRemove = m_uavGadget; + setGadget(newGadget); + m_uavGadgetManager->setCurrentGadget(newGadget); + im->removeGadget(gadgetToRemove); +} diff --git a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.h b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.h index 494f456f0..aaf051ba7 100644 --- a/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.h +++ b/ground/openpilotgcs/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.h @@ -67,21 +67,25 @@ public: UAVGadgetView(UAVGadgetManager *uavGadgetManager, IUAVGadget *uavGadget = 0, QWidget *parent = 0); virtual ~UAVGadgetView(); - void removeGadget(); IUAVGadget *gadget() const; void setGadget(IUAVGadget *uavGadget); bool hasGadget(IUAVGadget *uavGadget) const; - int indexOfClassId(QString classId); + void removeGadget(); + void showToolbar(bool show); + void saveState(QSettings *qSettings); + void restoreState(QSettings *qSettings); + public slots: void closeView(); - void listSelectionActivated(int index); private slots: + void listSelectionActivated(int index); void currentGadgetChanged(IUAVGadget *gadget); private: + int indexOfClassId(QString classId); void updateToolBar(); QPointer m_uavGadgetManager; diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro b/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro index d0aeeed1b..5b61364fc 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro @@ -99,7 +99,8 @@ HEADERS += $$UAVOBJECT_SYNTHETICS/accessorydesired.h \ $$UAVOBJECT_SYNTHETICS/oplinkstatus.h \ $$UAVOBJECT_SYNTHETICS/osdsettings.h \ $$UAVOBJECT_SYNTHETICS/waypoint.h \ - $$UAVOBJECT_SYNTHETICS/waypointactive.h + $$UAVOBJECT_SYNTHETICS/waypointactive.h \ + $$UAVOBJECT_SYNTHETICS/mpu6000settings.h SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \ $$UAVOBJECT_SYNTHETICS/baroaltitude.cpp \ @@ -178,4 +179,5 @@ SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \ $$UAVOBJECT_SYNTHETICS/oplinkstatus.cpp \ $$UAVOBJECT_SYNTHETICS/osdsettings.cpp \ $$UAVOBJECT_SYNTHETICS/waypoint.cpp \ - $$UAVOBJECT_SYNTHETICS/waypointactive.cpp + $$UAVOBJECT_SYNTHETICS/waypointactive.cpp \ + $$UAVOBJECT_SYNTHETICS/mpu6000settings.cpp diff --git a/ground/openpilotgcs/src/plugins/uploader/devicewidget.cpp b/ground/openpilotgcs/src/plugins/uploader/devicewidget.cpp index e9d33e784..081a847c2 100644 --- a/ground/openpilotgcs/src/plugins/uploader/devicewidget.cpp +++ b/ground/openpilotgcs/src/plugins/uploader/devicewidget.cpp @@ -35,12 +35,12 @@ deviceWidget::deviceWidget(QWidget *parent) : // Initialization of the Device icon display myDevice->verticalGroupBox_loaded->setVisible(false); myDevice->groupCustom->setVisible(false); - myDevice->youdont->setVisible(false); + myDevice->confirmCheckBox->setVisible(false); myDevice->gVDevice->setScene(new QGraphicsScene(this)); connect(myDevice->retrieveButton, SIGNAL(clicked()), this, SLOT(downloadFirmware())); connect(myDevice->updateButton, SIGNAL(clicked()), this, SLOT(uploadFirmware())); connect(myDevice->pbLoad, SIGNAL(clicked()), this, SLOT(loadFirmware())); - connect(myDevice->youdont, SIGNAL(stateChanged(int)), this, SLOT(confirmCB(int))); + connect(myDevice->confirmCheckBox, SIGNAL(stateChanged(int)), this, SLOT(confirmCB(int))); QPixmap pix = QPixmap(QString(":uploader/images/view-refresh.svg")); myDevice->statusIcon->setPixmap(pix); @@ -143,9 +143,28 @@ void deviceWidget::populate() */ void deviceWidget::freeze() { - myDevice->description->setEnabled(false); - myDevice->updateButton->setEnabled(false); - myDevice->retrieveButton->setEnabled(false); + updateButtons(false); +} + +void deviceWidget::updateButtons(bool enabled) +{ + if (!enabled) { + myDevice->description->setEnabled(false); + myDevice->pbLoad->setEnabled(false); + myDevice->confirmCheckBox->setEnabled(false); + myDevice->updateButton->setEnabled(false); + myDevice->retrieveButton->setEnabled(false); + } + else { + myDevice->description->setEnabled(true); + // Load button (i.e. choose file) is always enabled + myDevice->pbLoad->setEnabled(true); + myDevice->confirmCheckBox->setEnabled(true); + // Update/Upload button is enabled if the "I know what I'm doing!" check box is checked + myDevice->updateButton->setEnabled(myDevice->confirmCheckBox->checkState() == Qt::Checked); + // Retreive/Download button is always enabled + myDevice->retrieveButton->setEnabled(true); + } } /** @@ -222,12 +241,7 @@ void deviceWidget::dfuStatus(QString str) void deviceWidget::confirmCB(int value) { - if(value==Qt::Checked) - { - myDevice->updateButton->setEnabled(true); - } - else - myDevice->updateButton->setEnabled(false); + updateButtons(true); } /** @@ -261,6 +275,9 @@ void deviceWidget::loadFirmware() filename = setOpenFileName(); + myDevice->confirmCheckBox->setVisible(false); + myDevice->confirmCheckBox->setChecked(false); + if (filename.isEmpty()) { status("Empty filename", STATUSICON_FAIL); return; @@ -273,58 +290,46 @@ void deviceWidget::loadFirmware() } loadedFW = file.readAll(); - myDevice->youdont->setVisible(false); - myDevice->youdont->setChecked(false); + QByteArray desc = loadedFW.right(100); QPixmap px; - if(loadedFW.length()>m_dfu->devices[deviceID].SizeOfCode) + if (loadedFW.length()>m_dfu->devices[deviceID].SizeOfCode) { myDevice->lblCRCL->setText(tr("Can't calculate, file too big for device")); - else + } + else { myDevice->lblCRCL->setText( QString::number(DFUObject::CRCFromQBArray(loadedFW,m_dfu->devices[deviceID].SizeOfCode))); + } //myDevice->lblFirmwareSizeL->setText(QString("Firmware size: ")+QVariant(loadedFW.length()).toString()+ QString(" bytes")); if (populateLoadedStructuredDescription(desc)) { - myDevice->youdont->setChecked(true); + myDevice->confirmCheckBox->setChecked(true); myDevice->verticalGroupBox_loaded->setVisible(true); myDevice->groupCustom->setVisible(false); - if(myDevice->lblCRC->text()==myDevice->lblCRCL->text()) - { - myDevice->statusLabel->setText(tr("The board has the same firmware as loaded. No need to update")); + if (myDevice->lblCRC->text() == myDevice->lblCRCL->text()) { + myDevice->statusLabel->setText(tr("The board has the same firmware as loaded. No need to update.")); px.load(QString(":/uploader/images/warning.svg")); - } - else if(myDevice->lblDevName->text()!=myDevice->lblBrdNameL->text()) - { + } else if (myDevice->lblDevName->text() != myDevice->lblBrdNameL->text()) { myDevice->statusLabel->setText(tr("WARNING: the loaded firmware is for different hardware. Do not update!")); px.load(QString(":/uploader/images/error.svg")); - } - else if(QDateTime::fromString(onBoardDescription.gitDate)>QDateTime::fromString(LoadedDescription.gitDate)) - { + } else if (QDateTime::fromString(onBoardDescription.gitDate) > QDateTime::fromString(LoadedDescription.gitDate)) { myDevice->statusLabel->setText(tr("The board has newer firmware than loaded. Are you sure you want to update?")); px.load(QString(":/uploader/images/warning.svg")); - } - else if(!LoadedDescription.gitTag.startsWith("RELEASE",Qt::CaseSensitive)) - { - myDevice->statusLabel->setText(tr("The loaded firmware is untagged or custom build. Update only if it was received from a trusted source (official website or your own build)")); + } else if (!LoadedDescription.gitTag.startsWith("RELEASE", Qt::CaseSensitive)) { + myDevice->statusLabel->setText(tr("The loaded firmware is untagged or custom build. Update only if it was received from a trusted source (official website or your own build).")); px.load(QString(":/uploader/images/warning.svg")); - } - else - { - myDevice->statusLabel->setText(tr("This is the tagged officially released OpenPilot firmware")); + } else { + myDevice->statusLabel->setText(tr("This is the tagged officially released OpenPilot firmware.")); px.load(QString(":/uploader/images/gtk-info.svg")); } - } - else - { - myDevice->statusLabel->setText(tr("WARNING: the loaded firmware was not packaged with the OpenPilot format. Do not update unless you know what you are doing")); + } else { + myDevice->statusLabel->setText(tr("WARNING: the loaded firmware was not packaged with the OpenPilot format. Do not update unless you know what you are doing.")); px.load(QString(":/uploader/images/error.svg")); - myDevice->youdont->setChecked(false); - myDevice->youdont->setVisible(true); + myDevice->confirmCheckBox->setChecked(false); + myDevice->confirmCheckBox->setVisible(true); myDevice->verticalGroupBox_loaded->setVisible(false); myDevice->groupCustom->setVisible(true); } myDevice->statusIcon->setPixmap(px); - //myDevice->updateButton->setEnabled(true); - } /** @@ -332,10 +337,14 @@ void deviceWidget::loadFirmware() */ void deviceWidget::uploadFirmware() { - myDevice->updateButton->setEnabled(false); + // clear progress bar now + // this avoids displaying an error message and the progress at 100% at the same time + setProgress(0); + updateButtons(false); + if (!m_dfu->devices[deviceID].Writable) { status("Device not writable!", STATUSICON_FAIL); - myDevice->updateButton->setEnabled(true); + updateButtons(true); return; } @@ -359,7 +368,7 @@ void deviceWidget::uploadFirmware() // These firmwares are designed to be backwards compatible } else if (firmwareBoard != board) { status("Error: firmware does not match board", STATUSICON_FAIL); - myDevice->updateButton->setEnabled(true); + updateButtons(true); return; } // Check the firmware embedded in the file: @@ -367,7 +376,7 @@ void deviceWidget::uploadFirmware() QByteArray fileHash = QCryptographicHash::hash(loadedFW.left(loadedFW.length()-100), QCryptographicHash::Sha1); if (firmwareHash != fileHash) { status("Error: firmware file corrupt", STATUSICON_FAIL); - myDevice->updateButton->setEnabled(true); + updateButtons(true); return; } } else { @@ -376,16 +385,16 @@ void deviceWidget::uploadFirmware() descriptionArray.clear(); } - status("Starting firmware upload", STATUSICON_RUNNING); + emit uploadStarted(); + // We don't know which device was used previously, so we // are cautious and reenter DFU for this deviceID: - emit uploadStarted(); if(!m_dfu->enterDFU(deviceID)) { - status("Error:Could not enter DFU mode", STATUSICON_FAIL); - myDevice->updateButton->setEnabled(true); emit uploadEnded(false); + status("Error:Could not enter DFU mode", STATUSICON_FAIL); + updateButtons(true); return; } OP_DFU::Status ret=m_dfu->StatusRequest(); @@ -395,13 +404,14 @@ void deviceWidget::uploadFirmware() connect(m_dfu, SIGNAL(progressUpdated(int)), this, SLOT(setProgress(int))); connect(m_dfu, SIGNAL(operationProgress(QString)), this, SLOT(dfuStatus(QString))); connect(m_dfu, SIGNAL(uploadFinished(OP_DFU::Status)), this, SLOT(uploadFinished(OP_DFU::Status))); - bool retstatus = m_dfu->UploadFirmware(filename,verify, deviceID); - if(!retstatus ) { - status("Could not start upload", STATUSICON_FAIL); - myDevice->updateButton->setEnabled(true); + bool retstatus = m_dfu->UploadFirmware(filename, verify, deviceID); + if (!retstatus) { emit uploadEnded(false); + status("Could not start upload!", STATUSICON_FAIL); + updateButtons(true); return; } + status("Uploading, please wait...", STATUSICON_RUNNING); } @@ -410,29 +420,43 @@ void deviceWidget::uploadFirmware() */ void deviceWidget::downloadFirmware() { + // clear progress bar now + // this avoids displaying an error message and the progress at 100% at the same time + setProgress(0); + updateButtons(false); + if (!m_dfu->devices[deviceID].Readable) { myDevice->statusLabel->setText(QString("Device not readable!")); + status("Device not readable!", STATUSICON_FAIL); + updateButtons(true); return; } - myDevice->retrieveButton->setEnabled(false); filename = setSaveFileName(); - if (filename.isEmpty()) { status("Empty filename", STATUSICON_FAIL); + updateButtons(true); return; } - status("Downloading firmware from device", STATUSICON_RUNNING); + status("Starting firmware download", STATUSICON_RUNNING); + emit downloadStarted(); + connect(m_dfu, SIGNAL(progressUpdated(int)), this, SLOT(setProgress(int))); connect(m_dfu, SIGNAL(downloadFinished()), this, SLOT(downloadFinished())); + downloadedFirmware.clear(); // Empty the byte array bool ret = m_dfu->DownloadFirmware(&downloadedFirmware,deviceID); - if(!ret) { + + if (!ret) { + emit downloadEnded(false); status("Could not start download!", STATUSICON_FAIL); + updateButtons(true); return; } - status("Download started, please wait", STATUSICON_RUNNING); + + status("Downloading, please wait...", STATUSICON_RUNNING); + return; } /** @@ -442,10 +466,13 @@ void deviceWidget::downloadFinished() { disconnect(m_dfu, SIGNAL(downloadFinished()), this, SLOT(downloadFinished())); disconnect(m_dfu, SIGNAL(progressUpdated(int)), this, SLOT(setProgress(int))); - status("Download successful", STATUSICON_OK); + // Now save the result (use the utility function from OP_DFU) m_dfu->SaveByteArrayToFile(filename, downloadedFirmware); - myDevice->retrieveButton->setEnabled(true); + + emit downloadEnded(true); + status("Download successful", STATUSICON_OK); + updateButtons(true); } /** @@ -453,13 +480,14 @@ void deviceWidget::downloadFinished() */ void deviceWidget::uploadFinished(OP_DFU::Status retstatus) { - myDevice->updateButton->setEnabled(true); disconnect(m_dfu, SIGNAL(uploadFinished(OP_DFU::Status)), this, SLOT(uploadFinished(OP_DFU::Status))); disconnect(m_dfu, SIGNAL(progressUpdated(int)), this, SLOT(setProgress(int))); disconnect(m_dfu, SIGNAL(operationProgress(QString)), this, SLOT(dfuStatus(QString))); - if(retstatus != OP_DFU::Last_operation_Success) { - status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); + + if (retstatus != OP_DFU::Last_operation_Success) { emit uploadEnded(false); + status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); + updateButtons(true); return; } else if (!descriptionArray.isEmpty()) { @@ -467,9 +495,10 @@ void deviceWidget::uploadFinished(OP_DFU::Status retstatus) status(QString("Updating description"), STATUSICON_RUNNING); repaint(); // Make sure the text above shows right away retstatus = m_dfu->UploadDescription(descriptionArray); - if( retstatus != OP_DFU::Last_operation_Success) { - status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); + if (retstatus != OP_DFU::Last_operation_Success) { emit uploadEnded(false); + status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); + updateButtons(true); return; } @@ -478,16 +507,19 @@ void deviceWidget::uploadFinished(OP_DFU::Status retstatus) status(QString("Updating description"), STATUSICON_RUNNING); repaint(); // Make sure the text above shows right away retstatus = m_dfu->UploadDescription(myDevice->description->text()); - if( retstatus != OP_DFU::Last_operation_Success) { - status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); + if (retstatus != OP_DFU::Last_operation_Success) { emit uploadEnded(false); + status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); + updateButtons(true); return; } } + populate(); + emit uploadEnded(true); status("Upload successful", STATUSICON_OK); - + updateButtons(true); } /** diff --git a/ground/openpilotgcs/src/plugins/uploader/devicewidget.h b/ground/openpilotgcs/src/plugins/uploader/devicewidget.h index eaf8c6a0f..bc44b8883 100644 --- a/ground/openpilotgcs/src/plugins/uploader/devicewidget.h +++ b/ground/openpilotgcs/src/plugins/uploader/devicewidget.h @@ -49,7 +49,7 @@ class UPLOADER_EXPORT deviceWidget : public QWidget { Q_OBJECT public: - deviceWidget( QWidget *parent = 0); + deviceWidget(QWidget *parent = 0); void setDeviceID(int devID); void setDfu(DFUObject* dfu); void populate(); @@ -57,6 +57,7 @@ public: typedef enum { STATUSICON_OK, STATUSICON_RUNNING, STATUSICON_FAIL, STATUSICON_INFO} StatusIcon; QString setOpenFileName(); QString setSaveFileName(); + private: deviceDescriptorStruct onBoardDescription; deviceDescriptorStruct LoadedDescription; @@ -71,10 +72,14 @@ private: void status(QString str, StatusIcon ic); bool populateBoardStructuredDescription(QByteArray arr); bool populateLoadedStructuredDescription(QByteArray arr); + void updateButtons(bool enabled); signals: void uploadStarted(); void uploadEnded(bool success); + void downloadStarted(); + void downloadEnded(bool success); + public slots: void uploadFirmware(); void loadFirmware(); diff --git a/ground/openpilotgcs/src/plugins/uploader/devicewidget.ui b/ground/openpilotgcs/src/plugins/uploader/devicewidget.ui index 4fea11eb5..b7c7849da 100644 --- a/ground/openpilotgcs/src/plugins/uploader/devicewidget.ui +++ b/ground/openpilotgcs/src/plugins/uploader/devicewidget.ui @@ -101,9 +101,9 @@ - + - I know what I'm doing + I know what I'm doing! true diff --git a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp index 508003f9f..077e6a8e7 100755 --- a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp +++ b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp @@ -120,6 +120,8 @@ void UploaderGadgetWidget::connectSignalSlot(QWidget *widget) { connect(qobject_cast(widget),SIGNAL(uploadStarted()),this,SLOT(uploadStarted())); connect(qobject_cast(widget),SIGNAL(uploadEnded(bool)),this,SLOT(uploadEnded(bool))); + connect(qobject_cast(widget),SIGNAL(downloadStarted()),this,SLOT(downloadStarted())); + connect(qobject_cast(widget),SIGNAL(downloadEnded(bool)),this,SLOT(downloadEnded(bool))); } FlightStatus *UploaderGadgetWidget::getFlightStatus() @@ -398,7 +400,7 @@ void UploaderGadgetWidget::systemReset() delete dfu; dfu = NULL; } - m_config->textBrowser->clear(); + clearLog(); log("Board Reset initiated."); goToBootloader(); } @@ -470,8 +472,15 @@ void UploaderGadgetWidget::commonSystemBoot(bool safeboot) // Freeze the tabs, they are not useful anymore and their buttons // will cause segfaults or weird stuff if we use them. for (int i=0; i< m_config->systemElements->count(); i++) { - deviceWidget *qw = (deviceWidget*)m_config->systemElements->widget(i); - qw->freeze(); + // OP-682 arriving here too "early" (before the devices are refreshed) was leading to a crash + // OP-682 the crash was due to an unchecked cast in the line below that would cast a RunningDeviceGadget to a DeviceGadget + deviceWidget *qw = dynamic_cast(m_config->systemElements->widget(i)); + if (qw) { + // OP-682 fixed a second crash by disabling *all* buttons in the device widget + // disabling the buttons is only half of the solution as even if the buttons are enabled + // the app should not crash + qw->freeze(); + } } } currentStep = IAP_STATE_READY; @@ -479,6 +488,7 @@ void UploaderGadgetWidget::commonSystemBoot(bool safeboot) delete dfu; // Frees up the USB/Serial port too dfu = NULL; } + bool UploaderGadgetWidget::autoUpdateCapable() { return QDir(":/build").exists(); @@ -754,15 +764,44 @@ void UploaderGadgetWidget::cancel() void UploaderGadgetWidget::uploadStarted() { + m_config->haltButton->setEnabled(false); m_config->bootButton->setEnabled(false); m_config->safeBootButton->setEnabled(false); + m_config->resetButton->setEnabled(false); + m_config->rescueButton->setEnabled(false); } void UploaderGadgetWidget::uploadEnded(bool succeed) { Q_UNUSED(succeed); + // device is halted so no halt + m_config->haltButton->setEnabled(false); m_config->bootButton->setEnabled(true); m_config->safeBootButton->setEnabled(true); + // device is halted so no reset + m_config->resetButton->setEnabled(false); + m_config->rescueButton->setEnabled(true); +} + +void UploaderGadgetWidget::downloadStarted() +{ + m_config->haltButton->setEnabled(false); + m_config->bootButton->setEnabled(false); + m_config->safeBootButton->setEnabled(false); + m_config->resetButton->setEnabled(false); + m_config->rescueButton->setEnabled(false); +} + +void UploaderGadgetWidget::downloadEnded(bool succeed) +{ + Q_UNUSED(succeed); + // device is halted so no halt + m_config->haltButton->setEnabled(false); + m_config->bootButton->setEnabled(true); + m_config->safeBootButton->setEnabled(true); + // device is halted so no reset + m_config->resetButton->setEnabled(false); + m_config->rescueButton->setEnabled(true); } /** @@ -770,9 +809,9 @@ void UploaderGadgetWidget::uploadEnded(bool succeed) */ void UploaderGadgetWidget::log(QString str) { + qDebug() << str; m_config->textBrowser->append(str); m_config->textBrowser->repaint(); - } void UploaderGadgetWidget::clearLog() @@ -819,6 +858,7 @@ void UploaderGadgetWidget::error(QString errorString, int errorNumber) msgBox.exec(); m_config->boardStatus->setText(errorString); } + /** Shows a message box with an information string. diff --git a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.h b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.h index 9f4702e2f..3e3b0f504 100755 --- a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.h +++ b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.h @@ -115,7 +115,8 @@ private slots: void cancel(); void uploadStarted(); void uploadEnded(bool succeed); - + void downloadStarted(); + void downloadEnded(bool succeed); }; #endif // UPLOADERGADGETWIDGET_H diff --git a/shared/uavobjectdefinition/mpu6000settings.xml b/shared/uavobjectdefinition/mpu6000settings.xml new file mode 100644 index 000000000..943243fa7 --- /dev/null +++ b/shared/uavobjectdefinition/mpu6000settings.xml @@ -0,0 +1,38 @@ + + + Settings for the @ref MPU6000 sensor used on CC3D and Revolution. Reboot the board for this to takes effect + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +