1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-21 11:54:15 +01:00

Merge branch 'master' into OP-483_os_release-packaging

This commit is contained in:
Oleg Semyonov 2011-05-15 21:32:20 +03:00
commit 39d4f23b67
31 changed files with 5316 additions and 4909 deletions

View File

@ -105,6 +105,11 @@ C: Gary Mortimer and the Scorpion
D: March 2011 D: March 2011
V: http://vimeo.com/22104334 V: http://vimeo.com/22104334
M: First Y6 OpenPilot flight
C: Sami Korhonen (Sambas)
D: May 2011
V: http://www.vimeo.com/23637586
M: First CopterControl flight on a Flybarless Heli M: First CopterControl flight on a Flybarless Heli
C: ? C: ?
D: ? D: ?

View File

@ -205,6 +205,7 @@ SRC += $(PIOSSTM32F10X)/pios_usb_hid_prop.c
SRC += $(PIOSSTM32F10X)/pios_usb_hid_pwr.c SRC += $(PIOSSTM32F10X)/pios_usb_hid_pwr.c
## PIOS Hardware (Common) ## PIOS Hardware (Common)
SRC += $(PIOSCOMMON)/pios_flashfs_objlist.c
SRC += $(PIOSCOMMON)/pios_flash_w25x.c SRC += $(PIOSCOMMON)/pios_flash_w25x.c
SRC += $(PIOSCOMMON)/pios_adxl345.c SRC += $(PIOSCOMMON)/pios_adxl345.c
SRC += $(PIOSCOMMON)/pios_com.c SRC += $(PIOSCOMMON)/pios_com.c

View File

@ -92,6 +92,7 @@ void OpenPilotInit()
#ifdef ERASE_FLASH #ifdef ERASE_FLASH
PIOS_Flash_W25X_EraseChip(); PIOS_Flash_W25X_EraseChip();
while(TRUE){};
#endif #endif
/* Initialize modules */ /* Initialize modules */

View File

@ -681,6 +681,8 @@ void PIOS_Board_Init(void) {
PIOS_Flash_W25X_Init(pios_spi_flash_accel_id); PIOS_Flash_W25X_Init(pios_spi_flash_accel_id);
PIOS_ADXL345_Attach(pios_spi_flash_accel_id); PIOS_ADXL345_Attach(pios_spi_flash_accel_id);
PIOS_FLASHFS_Init();
#if defined(PIOS_INCLUDE_SPEKTRUM) #if defined(PIOS_INCLUDE_SPEKTRUM)
/* SPEKTRUM init must come before comms */ /* SPEKTRUM init must come before comms */
PIOS_SPEKTRUM_Init(); PIOS_SPEKTRUM_Init();

View File

@ -142,17 +142,18 @@ static void AttitudeTask(void *parameters)
FlightStatusData flightStatus; FlightStatusData flightStatus;
FlightStatusGet(&flightStatus); FlightStatusGet(&flightStatus);
if(xTaskGetTickCount() < 10000) { if(xTaskGetTickCount() < 7000) {
// For first 5 seconds use accels to get gyro bias // Force settings update to make sure rotation loaded
settingsUpdatedCb(AttitudeSettingsHandle());
// For first 7 seconds use accels to get gyro bias
accelKp = 1; accelKp = 1;
// Decrease the rate of gyro learning during init accelKi = 0.9;
accelKi = .5 / (1 + xTaskGetTickCount() / 5000); yawBiasRate = 0.23;
yawBiasRate = 0.01 / (1 + xTaskGetTickCount() / 5000);
init = 0; init = 0;
} }
else if (zero_during_arming && (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMING)) { else if (zero_during_arming && (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMING)) {
accelKi = .01; accelKi = 0.9;
yawBiasRate = 0.1; yawBiasRate = 0.23;
init = 0; init = 0;
} else if (init == 0) { } else if (init == 0) {
settingsUpdatedCb(AttitudeSettingsHandle()); settingsUpdatedCb(AttitudeSettingsHandle());

View File

@ -30,6 +30,7 @@
#include "openpilot.h" #include "openpilot.h"
#include "firmwareiap.h" #include "firmwareiap.h"
#include "firmwareiapobj.h" #include "firmwareiapobj.h"
#include "flightstatus.h"
// Private constants // Private constants
#define IAP_CMD_STEP_1 1122 #define IAP_CMD_STEP_1 1122
@ -156,6 +157,16 @@ static void FirmwareIAPCallback(UAVObjEvent* ev)
case IAP_STATE_STEP_2: case IAP_STATE_STEP_2:
if( data.Command == IAP_CMD_STEP_3 ) { if( data.Command == IAP_CMD_STEP_3 ) {
if( delta > iap_time_3_low_end && delta < iap_time_3_high_end ) { if( delta > iap_time_3_low_end && delta < iap_time_3_high_end ) {
FlightStatusData flightStatus;
FlightStatusGet(&flightStatus);
if(flightStatus.Armed != FLIGHTSTATUS_ARMED_DISARMED) {
// Abort any attempts if not disarmed
iap_state = IAP_STATE_READY;
break;
}
// we've met the three sequence of command numbers // we've met the three sequence of command numbers
// we've met the time requirements. // we've met the time requirements.
PIOS_IAP_SetRequest1(); PIOS_IAP_SetRequest1();

View File

@ -63,7 +63,7 @@ static float GravityAccel(float latitude, float longitude, float altitude);
// Private constants // Private constants
//#define FULL_COLD_RESTART // uncomment this to tell the GPS to do a FULL COLD restart //#define FULL_COLD_RESTART // uncomment this to tell the GPS to do a FULL COLD restart
//#define DISABLE_GPS_TRESHOLD // //#define DISABLE_GPS_THRESHOLD //
#define GPS_TIMEOUT_MS 500 #define GPS_TIMEOUT_MS 500
#define GPS_COMMAND_RESEND_TIMEOUT_MS 2000 #define GPS_COMMAND_RESEND_TIMEOUT_MS 2000
@ -154,7 +154,7 @@ static void gpsTask(void *parameters)
} }
#endif #endif
#ifdef DISABLE_GPS_TRESHOLD #ifdef DISABLE_GPS_THRESHOLD
PIOS_COM_SendStringNonBlocking(gpsPort, "$PMTK397,0*23\r\n"); PIOS_COM_SendStringNonBlocking(gpsPort, "$PMTK397,0*23\r\n");
#endif #endif

View File

@ -52,14 +52,13 @@ endif
FLASH_TOOL = OPENOCD FLASH_TOOL = OPENOCD
# List of modules to include # List of modules to include
MODULES = Actuator Telemetry GPS ManualControl Altitude AHRSComms Stabilization Guidance FirmwareIAP FlightPlan MODULES = Actuator Telemetry GPS ManualControl Altitude AHRSComms Stabilization Guidance FirmwareIAP
PYMODULES = FlightPlan
#MODULES = Telemetry Example #MODULES = Telemetry Example
#MODULES = Telemetry MK/MKSerial #MODULES = Telemetry MK/MKSerial
#MODULES = Telemetry #MODULES = Telemetry
#MODULES += Osd/OsdEtStd #MODULES += Osd/OsdEtStd
# MCU name, submodel and board # MCU name, submodel and board
# - MCU used for compiler-option (-mcpu) # - MCU used for compiler-option (-mcpu)
# - MODEL used for linker-script name (-T) and passed as define # - MODEL used for linker-script name (-T) and passed as define
@ -124,17 +123,19 @@ UAVOBJSYNTHDIR = $(OUTDIR)/../uavobject-synthetics/flight
# List C source files here. (C dependencies are automatically generated.) # List C source files here. (C dependencies are automatically generated.)
# use file-extension c for "c-only"-files # use file-extension c for "c-only"-files
MODNAMES = $(notdir ${MODULES}) MODNAMES = $(notdir ${MODULES} ${PYMODULES})
ifndef TESTAPP ifndef TESTAPP
## PyMite files ## PyMite files and modules
SRC += $(OUTDIR)/pmlib_img.c SRC += $(OUTDIR)/pmlib_img.c
SRC += $(OUTDIR)/pmlib_nat.c SRC += $(OUTDIR)/pmlib_nat.c
SRC += $(OUTDIR)/pmlibusr_img.c SRC += $(OUTDIR)/pmlibusr_img.c
SRC += $(OUTDIR)/pmlibusr_nat.c SRC += $(OUTDIR)/pmlibusr_nat.c
SRC += $(wildcard ${PYMITEVM}/*.c) PYSRC += $(wildcard ${PYMITEVM}/*.c)
SRC += $(wildcard ${PYMITEPLAT}/*.c) PYSRC += $(wildcard ${PYMITEPLAT}/*.c)
PYSRC += ${foreach MOD, ${PYMODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}}
SRC += $(PYSRC)
## MODULES ## MODULES
SRC += ${foreach MOD, ${MODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}} SRC += ${foreach MOD, ${MODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}}
@ -317,7 +318,7 @@ EXTRAINCDIRS += $(RTOSSRCDIR)/portable/GCC/ARM_CM3
EXTRAINCDIRS += $(AHRSBOOTLOADERINC) EXTRAINCDIRS += $(AHRSBOOTLOADERINC)
EXTRAINCDIRS += $(PYMITEINC) EXTRAINCDIRS += $(PYMITEINC)
EXTRAINCDIRS += ${foreach MOD, ${MODULES}, $(OPMODULEDIR)/${MOD}/inc} ${OPMODULEDIR}/System/inc EXTRAINCDIRS += ${foreach MOD, ${MODULES} ${PYMODULES}, $(OPMODULEDIR)/${MOD}/inc} ${OPMODULEDIR}/System/inc
# List any extra directories to look for library files here. # List any extra directories to look for library files here.
@ -481,7 +482,7 @@ LSTFILES = $(addprefix $(OUTDIR)/, $(addsuffix .lst, $(ALLSRCBASE)))
DEPFILES = $(addprefix $(OUTDIR)/dep/, $(addsuffix .o.d, $(ALLSRCBASE))) DEPFILES = $(addprefix $(OUTDIR)/dep/, $(addsuffix .o.d, $(ALLSRCBASE)))
# Default target. # Default target.
all: gencode gccversion build all: gccversion build
ifeq ($(LOADFORMAT),ihex) ifeq ($(LOADFORMAT),ihex)
build: elf hex lss sym build: elf hex lss sym
@ -500,6 +501,8 @@ endif
# Generate intermediate code # Generate intermediate code
gencode: ${OUTDIR}/InitMods.c ${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h gencode: ${OUTDIR}/InitMods.c ${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h
$(PYSRC): gencode
# Generate code for module initialization # Generate code for module initialization
${OUTDIR}/InitMods.c: Makefile ${OUTDIR}/InitMods.c: Makefile
@echo $(MSG_MODINIT) $(call toprel, $@) @echo $(MSG_MODINIT) $(call toprel, $@)

View File

@ -222,6 +222,14 @@ int8_t PIOS_Flash_W25X_WriteData(uint32_t addr, uint8_t * data, uint16_t len)
return 0; return 0;
} }
/**
* @brief Read data from a location in flash memory
* @param[in] addr Address in flash to write to
* @param[in] data Pointer to data to write from flash
* @param[in] len Length of data to write (max 256 bytes)
* @return Zero if success or error code
* @retval -1 Unable to claim SPI bus
*/
int8_t PIOS_Flash_W25X_ReadData(uint32_t addr, uint8_t * data, uint16_t len) int8_t PIOS_Flash_W25X_ReadData(uint32_t addr, uint8_t * data, uint16_t len)
{ {
if(PIOS_Flash_W25X_ClaimBus() == -1) if(PIOS_Flash_W25X_ClaimBus() == -1)

View File

@ -0,0 +1,294 @@
/**
******************************************************************************
*
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_FLASHFS_OBJLIST Object list based flash filesystem (low ram)
* @{
*
* @file pios_flashfs_objlist.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief A file system for storing UAVObject in flash chip
* @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
*/
#include "openpilot.h"
#include "uavobjectmanager.h"
// Private functions
static int32_t PIOS_FLASHFS_CleabObjectTableHeader();
static int32_t PIOS_FLASHFS_GetObjAddress(uint32_t objId, uint16_t instId);
static int32_t PIOS_FLASHFS_GetNewAddress(uint32_t objId, uint16_t instId);
// Private variables
static int32_t numObjects = -1;
// Private structures
// Header for objects in the file system table
struct objectHeader {
uint32_t objMagic;
uint32_t objId;
uint32_t instId;
uint32_t address;
} __attribute__((packed));;
struct fileHeader {
uint32_t id;
uint16_t instId;
uint16_t size;
} __attribute__((packed));
#define OBJECT_TABLE_MAGIC 0x85FB3C33
#define OBJ_MAGIC 0x3015AE71
#define OBJECT_TABLE_START 0x00000010
#define OBJECT_TABLE_END 0x00001000
#define SECTOR_SIZE 0x00001000
/**
* @brief Initialize the flash object setting FS
* @return 0 if success, -1 if failure
*/
int32_t PIOS_FLASHFS_Init()
{
// Check for valid object table or create one
uint32_t object_table_magic;
if (PIOS_Flash_W25X_ReadData(0, (uint8_t *)&object_table_magic, sizeof(object_table_magic)) != 0)
return -1;
if(object_table_magic != OBJECT_TABLE_MAGIC) {
if(PIOS_FLASHFS_CleabObjectTableHeader() < 0)
return -1;
}
int32_t addr = OBJECT_TABLE_START;
struct objectHeader header;
numObjects = 0;
// Loop through header area while objects detect to count how many saved
while(addr < OBJECT_TABLE_END) {
// Read the instance data
if (PIOS_Flash_W25X_ReadData(addr, (uint8_t *)&header, sizeof(header)) != 0)
return -1;
// Counting number of valid headers
if(header.objMagic != OBJ_MAGIC)
break;
numObjects++;
addr += sizeof(header);
}
return 0;
}
/**
* @brief Erase the headers for all objects in the flash chip
* @return 0 if successful, -1 if not
*/
static int32_t PIOS_FLASHFS_CleabObjectTableHeader()
{
if(PIOS_Flash_W25X_EraseSector(OBJECT_TABLE_START) != 0)
return -1;
uint32_t object_table_magic = OBJECT_TABLE_MAGIC;
if (PIOS_Flash_W25X_WriteData(0, (uint8_t *)&object_table_magic, sizeof(object_table_magic)) != 0)
return -1;
return 0;
}
/**
* @brief Get the address of an object
* @param obj UAVObjHandle for that object
* @parma instId Instance id for that object
* @return address if successful, -1 if not found
*/
static int32_t PIOS_FLASHFS_GetObjAddress(uint32_t objId, uint16_t instId)
{
int32_t addr = OBJECT_TABLE_START;
struct objectHeader header;
// Loop through header area while objects detect to count how many saved
while(addr < OBJECT_TABLE_END) {
// Read the instance data
if (PIOS_Flash_W25X_ReadData(addr, (uint8_t *) &header, sizeof(header)) != 0)
return -1;
if(header.objMagic != OBJ_MAGIC)
break; // stop searching once hit first non-object header
else if (header.objId == objId && header.instId == instId)
break;
addr += sizeof(header);
}
if (header.objId == objId && header.instId == instId)
return header.address;
return -1;
}
/**
* @brief Returns an address for a new object and creates entry into object table
* @param[in] obj Object handle for object to be saved
* @param[in] instId The instance id of object to be saved
* @return 0 if success or error code
* @retval -1 Object not found
* @retval -2 No room in object table
* @retval -3 Unable to write entry into object table
* @retval -4 FS not initialized
*/
int32_t PIOS_FLASHFS_GetNewAddress(uint32_t objId, uint16_t instId)
{
struct objectHeader header;
if(numObjects < 0)
return -4;
// Don't worry about max size of flash chip here, other code will catch that
header.objMagic = OBJ_MAGIC;
header.objId = objId;
header.instId = instId;
header.address = OBJECT_TABLE_END + SECTOR_SIZE * numObjects;
int32_t addr = OBJECT_TABLE_START + sizeof(header) * numObjects;
// No room for this header in object table
if((addr + sizeof(header)) > OBJECT_TABLE_END)
return -2;
if(PIOS_Flash_W25X_WriteData(addr, (uint8_t *) &header, sizeof(header)) != 0)
return -3;
// This numObejcts value must stay consistent or there will be a break in the table
// and later the table will have bad values in it
numObjects++;
return header.address;
}
/**
* @brief Saves one object instance per sector
* @param[in] obj UAVObjHandle the object to save
* @param[in] instId The instance of the object to save
* @return 0 if success or -1 if failure
* @note This uses one sector on the flash chip per object so that no buffering in ram
* must be done when erasing the sector before a save
*/
int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data)
{
uint32_t objId = UAVObjGetID(obj);
int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId);
// Object currently not saved
if(addr < 0)
addr = PIOS_FLASHFS_GetNewAddress(objId, instId);
// Could not allocate a sector
if(addr < 0)
return -1;
struct fileHeader header = {
.id = objId,
.instId = instId,
.size = UAVObjGetNumBytes(obj)
};
if(PIOS_Flash_W25X_EraseSector(addr) != 0)
return -2;
// Save header
// This information IS redundant with the object table id. Oh well. Better safe than sorry.
if(PIOS_Flash_W25X_WriteData(addr, (uint8_t *) &header, sizeof(header)) != 0)
return -3;
// Save data
if(PIOS_Flash_W25X_WriteData(addr + sizeof(header), data, UAVObjGetNumBytes(obj)) != 0)
return -4;
return 0;
}
/**
* @brief Load one object instance per sector
* @param[in] obj UAVObjHandle the object to save
* @param[in] instId The instance of the object to save
* @return 0 if success or error code
* @retval -1 if object not in file table
* @retval -2 if unable to retrieve object header
* @retval -3 if loaded data instId or objId don't match
* @retval -4 if unable to retrieve instance data
* @note This uses one sector on the flash chip per object so that no buffering in ram
* must be done when erasing the sector before a save
*/
int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data)
{
uint32_t objId = UAVObjGetID(obj);
int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId);
// Object currently not saved
if(addr < 0)
return -1;
struct fileHeader header;
// Load header
// This information IS redundant with the object table id. Oh well. Better safe than sorry.
if(PIOS_Flash_W25X_ReadData(addr, (uint8_t *) &header, sizeof(header)) != 0)
return -2;
if((header.id != objId) || (header.instId != instId))
return -3;
// Read the instance data
if (PIOS_Flash_W25X_ReadData(addr + sizeof(header), data, UAVObjGetNumBytes(obj)) != 0)
return -4;
return 0;
}
/**
* @brief Delete object from flash
* @param[in] obj UAVObjHandle the object to save
* @param[in] instId The instance of the object to save
* @return 0 if success or error code
* @retval -1 if object not in file table
* @retval -2 Erase failed
* @note To avoid buffering the file table (1k ram!) the entry in the file table
* remains but destination sector is erased. This will make the load fail as the
* file header won't match the object. At next save it goes back there.
*/
int32_t PIOS_FLASHFS_ObjDelete(UAVObjHandle obj, uint16_t instId)
{
uint32_t objId = UAVObjGetID(obj);
int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId);
// Object currently not saved
if(addr < 0)
return -1;
if(PIOS_Flash_W25X_EraseSector(addr) != 0)
return -2;
return 0;
}

View File

@ -0,0 +1,37 @@
/**
******************************************************************************
*
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_FLASHFS_OBJLIST Object list based flash filesystem (low ram)
* @{
*
* @file pios_flashfs_objlist.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief A file system for storing UAVObject in flash chip
* @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
*/
#include "openpilot.h"
#include "uavobjectmanager.h"
int32_t PIOS_FLASHFS_Init();
int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data);
int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data);
int32_t PIOS_FLASHFS_ObjDelete(UAVObjHandle obj, uint16_t instId);

View File

@ -119,6 +119,7 @@
#if defined(PIOS_INCLUDE_FLASH) #if defined(PIOS_INCLUDE_FLASH)
#include <pios_flash_w25x.h> #include <pios_flash_w25x.h>
#include <pios_flashfs_objlist.h>
#endif #endif
#if defined(PIOS_INCLUDE_BL_HELPER) #if defined(PIOS_INCLUDE_BL_HELPER)

View File

@ -3171,6 +3171,8 @@
65FF4BE913791C3300146BE4 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; }; 65FF4BE913791C3300146BE4 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
65FF4BEA13791C3300146BE4 /* op_dfu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = op_dfu.c; sourceTree = "<group>"; }; 65FF4BEA13791C3300146BE4 /* op_dfu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = op_dfu.c; sourceTree = "<group>"; };
65FF4BEB13791C3300146BE4 /* pios_board.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pios_board.c; sourceTree = "<group>"; }; 65FF4BEB13791C3300146BE4 /* pios_board.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pios_board.c; sourceTree = "<group>"; };
65FF4D5E137EDEC100146BE4 /* pios_flashfs_objlist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pios_flashfs_objlist.c; sourceTree = "<group>"; };
65FF4D61137EFA4F00146BE4 /* pios_flashfs_objlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pios_flashfs_objlist.h; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
@ -7657,6 +7659,7 @@
65E8F03711EFF25C00BBF654 /* printf-stdarg.c */, 65E8F03711EFF25C00BBF654 /* printf-stdarg.c */,
6528CCB412E406B800CF5144 /* pios_adxl345.c */, 6528CCB412E406B800CF5144 /* pios_adxl345.c */,
6512D60712ED4CB8008175E5 /* pios_flash_w25x.c */, 6512D60712ED4CB8008175E5 /* pios_flash_w25x.c */,
65FF4D5E137EDEC100146BE4 /* pios_flashfs_objlist.c */,
); );
name = Common; name = Common;
path = ../../PiOS/Common; path = ../../PiOS/Common;
@ -7681,6 +7684,7 @@
65E8F03E11EFF25C00BBF654 /* pios_debug.h */, 65E8F03E11EFF25C00BBF654 /* pios_debug.h */,
65E8F03F11EFF25C00BBF654 /* pios_delay.h */, 65E8F03F11EFF25C00BBF654 /* pios_delay.h */,
65E8F04011EFF25C00BBF654 /* pios_exti.h */, 65E8F04011EFF25C00BBF654 /* pios_exti.h */,
65FF4D61137EFA4F00146BE4 /* pios_flashfs_objlist.h */,
65E8F04111EFF25C00BBF654 /* pios_gpio.h */, 65E8F04111EFF25C00BBF654 /* pios_gpio.h */,
65E8F04211EFF25C00BBF654 /* pios_hmc5843.h */, 65E8F04211EFF25C00BBF654 /* pios_hmc5843.h */,
65E8F04311EFF25C00BBF654 /* pios_i2c.h */, 65E8F04311EFF25C00BBF654 /* pios_i2c.h */,

View File

@ -41,10 +41,10 @@
* List of event queues and the eventmask associated with the queue. * List of event queues and the eventmask associated with the queue.
*/ */
struct ObjectEventListStruct { struct ObjectEventListStruct {
xQueueHandle queue; xQueueHandle queue;
UAVObjEventCallback cb; UAVObjEventCallback cb;
int32_t eventMask; int32_t eventMask;
struct ObjectEventListStruct* next; struct ObjectEventListStruct *next;
}; };
typedef struct ObjectEventListStruct ObjectEventList; typedef struct ObjectEventListStruct ObjectEventList;
@ -52,9 +52,9 @@ typedef struct ObjectEventListStruct ObjectEventList;
* List of object instances, holds the actual data structure and instance ID * List of object instances, holds the actual data structure and instance ID
*/ */
struct ObjectInstListStruct { struct ObjectInstListStruct {
void* data; void *data;
uint16_t instId; uint16_t instId;
struct ObjectInstListStruct* next; struct ObjectInstListStruct *next;
}; };
typedef struct ObjectInstListStruct ObjectInstList; typedef struct ObjectInstListStruct ObjectInstList;
@ -62,34 +62,48 @@ typedef struct ObjectInstListStruct ObjectInstList;
* List of objects registered in the object manager * List of objects registered in the object manager
*/ */
struct ObjectListStruct { struct ObjectListStruct {
uint32_t id; /** The object ID */ uint32_t id;
const char* name; /** The object name */ /** The object ID */
int8_t isMetaobject; /** Set to 1 if this is a metaobject */ const char *name;
int8_t isSingleInstance; /** Set to 1 if this object has a single instance */ /** The object name */
int8_t isSettings; /** Set to 1 if this object is a settings object */ int8_t isMetaobject;
uint16_t numBytes; /** Number of data bytes contained in the object (for a single instance) */ /** Set to 1 if this is a metaobject */
uint16_t numInstances; /** Number of instances */ int8_t isSingleInstance;
struct ObjectListStruct* linkedObj; /** Linked object, for regular objects this is the metaobject and for metaobjects it is the parent object */ /** Set to 1 if this object has a single instance */
ObjectInstList instances; /** List of object instances, instance 0 always exists */ int8_t isSettings;
ObjectEventList* events; /** Event queues registered on the object */ /** Set to 1 if this object is a settings object */
struct ObjectListStruct* next; /** Needed by linked list library (utlist.h) */ uint16_t numBytes;
/** Number of data bytes contained in the object (for a single instance) */
uint16_t numInstances;
/** Number of instances */
struct ObjectListStruct *linkedObj;
/** Linked object, for regular objects this is the metaobject and for metaobjects it is the parent object */
ObjectInstList instances;
/** List of object instances, instance 0 always exists */
ObjectEventList *events;
/** Event queues registered on the object */
struct ObjectListStruct *next;
/** Needed by linked list library (utlist.h) */
}; };
typedef struct ObjectListStruct ObjectList; typedef struct ObjectListStruct ObjectList;
// Private functions // Private functions
static int32_t sendEvent(ObjectList* obj, uint16_t instId, UAVObjEventType event); static int32_t sendEvent(ObjectList * obj, uint16_t instId,
static ObjectInstList* createInstance(ObjectList* obj, uint16_t instId); UAVObjEventType event);
static ObjectInstList* getInstance(ObjectList* obj, uint16_t instId); static ObjectInstList *createInstance(ObjectList * obj, uint16_t instId);
static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue, UAVObjEventCallback cb, int32_t eventMask); static ObjectInstList *getInstance(ObjectList * obj, uint16_t instId);
static int32_t disconnectObj(UAVObjHandle obj, xQueueHandle queue, UAVObjEventCallback cb); static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue,
UAVObjEventCallback cb, int32_t eventMask);
static int32_t disconnectObj(UAVObjHandle obj, xQueueHandle queue,
UAVObjEventCallback cb);
#if defined(PIOS_INCLUDE_SDCARD) #if defined(PIOS_INCLUDE_SDCARD)
static void objectFilename(ObjectList* obj, uint8_t* filename); static void objectFilename(ObjectList * obj, uint8_t * filename);
static void customSPrintf(uint8_t* buffer, uint8_t* format, ...); static void customSPrintf(uint8_t * buffer, uint8_t * format, ...);
#endif #endif
// Private variables // Private variables
static ObjectList* objList; static ObjectList *objList;
static xSemaphoreHandle mutex; static xSemaphoreHandle mutex;
static UAVObjMetadata defMetadata; static UAVObjMetadata defMetadata;
static UAVObjStats stats; static UAVObjStats stats;
@ -101,40 +115,40 @@ static UAVObjStats stats;
*/ */
int32_t UAVObjInitialize() int32_t UAVObjInitialize()
{ {
// Initialize variables // Initialize variables
objList = NULL; objList = NULL;
memset(&stats, 0, sizeof(UAVObjStats)); memset(&stats, 0, sizeof(UAVObjStats));
// Create mutex // Create mutex
mutex = xSemaphoreCreateRecursiveMutex(); mutex = xSemaphoreCreateRecursiveMutex();
if (mutex == NULL) if (mutex == NULL)
return -1; return -1;
// Initialize default metadata structure (metadata of metaobjects) // Initialize default metadata structure (metadata of metaobjects)
defMetadata.access = ACCESS_READWRITE; defMetadata.access = ACCESS_READWRITE;
defMetadata.gcsAccess = ACCESS_READWRITE; defMetadata.gcsAccess = ACCESS_READWRITE;
defMetadata.telemetryAcked = 1; defMetadata.telemetryAcked = 1;
defMetadata.telemetryUpdateMode = UPDATEMODE_ONCHANGE; defMetadata.telemetryUpdateMode = UPDATEMODE_ONCHANGE;
defMetadata.telemetryUpdatePeriod = 0; defMetadata.telemetryUpdatePeriod = 0;
defMetadata.gcsTelemetryAcked = 1; defMetadata.gcsTelemetryAcked = 1;
defMetadata.gcsTelemetryUpdateMode = UPDATEMODE_ONCHANGE; defMetadata.gcsTelemetryUpdateMode = UPDATEMODE_ONCHANGE;
defMetadata.gcsTelemetryUpdatePeriod = 0; defMetadata.gcsTelemetryUpdatePeriod = 0;
defMetadata.loggingUpdateMode = UPDATEMODE_ONCHANGE; defMetadata.loggingUpdateMode = UPDATEMODE_ONCHANGE;
defMetadata.loggingUpdatePeriod = 0; defMetadata.loggingUpdatePeriod = 0;
// Done // Done
return 0; return 0;
} }
/** /**
* Get the statistics counters * Get the statistics counters
* @param[out] statsOut The statistics counters will be copied there * @param[out] statsOut The statistics counters will be copied there
*/ */
void UAVObjGetStats(UAVObjStats* statsOut) void UAVObjGetStats(UAVObjStats * statsOut)
{ {
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
memcpy(statsOut, &stats, sizeof(UAVObjStats)); memcpy(statsOut, &stats, sizeof(UAVObjStats));
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
} }
/** /**
@ -142,9 +156,9 @@ void UAVObjGetStats(UAVObjStats* statsOut)
*/ */
void UAVObjClearStats() void UAVObjClearStats()
{ {
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
memset(&stats, 0, sizeof(UAVObjStats)); memset(&stats, 0, sizeof(UAVObjStats));
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
} }
/** /**
@ -160,91 +174,85 @@ void UAVObjClearStats()
* \return Object handle, or NULL if failure. * \return Object handle, or NULL if failure.
* \return * \return
*/ */
UAVObjHandle UAVObjRegister(uint32_t id, const char* name, const char* metaName, int32_t isMetaobject, UAVObjHandle UAVObjRegister(uint32_t id, const char *name,
int32_t isSingleInstance, int32_t isSettings, uint32_t numBytes, UAVObjInitializeCallback initCb) const char *metaName, int32_t isMetaobject,
int32_t isSingleInstance, int32_t isSettings,
uint32_t numBytes,
UAVObjInitializeCallback initCb)
{ {
ObjectList* objEntry; ObjectList *objEntry;
ObjectInstList* instEntry; ObjectInstList *instEntry;
ObjectList* metaObj; ObjectList *metaObj;
// Get lock // Get lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Check that the object is not already registered // Check that the object is not already registered
LL_FOREACH(objList, objEntry) LL_FOREACH(objList, objEntry) {
{ if (objEntry->id == id) {
if (objEntry->id == id) // Already registered, ignore
{ xSemaphoreGiveRecursive(mutex);
// Already registered, ignore return NULL;
xSemaphoreGiveRecursive(mutex); }
return NULL; }
}
}
// Create and append entry // Create and append entry
objEntry = (ObjectList*)pvPortMalloc(sizeof(ObjectList)); objEntry = (ObjectList *) pvPortMalloc(sizeof(ObjectList));
if (objEntry == NULL) if (objEntry == NULL) {
{ xSemaphoreGiveRecursive(mutex);
xSemaphoreGiveRecursive(mutex); return NULL;
return NULL; }
} objEntry->id = id;
objEntry->id = id; objEntry->name = name;
objEntry->name = name; objEntry->isMetaobject = (int8_t) isMetaobject;
objEntry->isMetaobject = (int8_t)isMetaobject; objEntry->isSingleInstance = (int8_t) isSingleInstance;
objEntry->isSingleInstance = (int8_t)isSingleInstance; objEntry->isSettings = (int8_t) isSettings;
objEntry->isSettings = (int8_t)isSettings; objEntry->numBytes = numBytes;
objEntry->numBytes = numBytes; objEntry->events = NULL;
objEntry->events = NULL; objEntry->numInstances = 0;
objEntry->numInstances = 0; objEntry->instances.data = NULL;
objEntry->instances.data = NULL; objEntry->instances.instId = 0xFFFF;
objEntry->instances.instId = 0xFFFF; objEntry->instances.next = NULL;
objEntry->instances.next = NULL; objEntry->linkedObj = NULL; // will be set later
objEntry->linkedObj = NULL; // will be set later LL_APPEND(objList, objEntry);
LL_APPEND(objList, objEntry);
// Create instance zero // Create instance zero
instEntry = createInstance(objEntry, 0); instEntry = createInstance(objEntry, 0);
if ( instEntry == NULL ) if (instEntry == NULL) {
{ xSemaphoreGiveRecursive(mutex);
xSemaphoreGiveRecursive(mutex); return NULL;
return NULL; }
} // Create metaobject and update linkedObj
if (isMetaobject) {
objEntry->linkedObj = NULL; // will be set later
} else {
// Create metaobject
metaObj =
(ObjectList *) UAVObjRegister(id + 1, metaName,
NULL, 1, 1, 0,
sizeof
(UAVObjMetadata),
NULL);
// Link two objects
objEntry->linkedObj = metaObj;
metaObj->linkedObj = objEntry;
}
// Create metaobject and update linkedObj // Initialize object fields and metadata to default values
if (isMetaobject) if (initCb != NULL) {
{ initCb((UAVObjHandle) objEntry, 0);
objEntry->linkedObj = NULL; // will be set later }
} // Attempt to load object's metadata from the SD card (not done directly on the metaobject, but through the object)
else if (!objEntry->isMetaobject) {
{ UAVObjLoad((UAVObjHandle) objEntry->linkedObj, 0);
// Create metaobject }
metaObj = (ObjectList*)UAVObjRegister(id+1, metaName, NULL, 1, 1, 0, sizeof(UAVObjMetadata), NULL); // If this is a settings object, attempt to load from SD card
// Link two objects if (objEntry->isSettings) {
objEntry->linkedObj = metaObj; UAVObjLoad((UAVObjHandle) objEntry, 0);
metaObj->linkedObj = objEntry; }
} // Release lock
xSemaphoreGiveRecursive(mutex);
// Initialize object fields and metadata to default values return (UAVObjHandle) objEntry;
if ( initCb != NULL )
{
initCb((UAVObjHandle)objEntry, 0);
}
// Attempt to load object's metadata from the SD card (not done directly on the metaobject, but through the object)
if ( !objEntry->isMetaobject )
{
UAVObjLoad( (UAVObjHandle)objEntry->linkedObj, 0 );
}
// If this is a settings object, attempt to load from SD card
if ( objEntry->isSettings )
{
UAVObjLoad( (UAVObjHandle)objEntry, 0 );
}
// Release lock
xSemaphoreGiveRecursive(mutex);
return (UAVObjHandle)objEntry;
} }
/** /**
@ -254,26 +262,24 @@ UAVObjHandle UAVObjRegister(uint32_t id, const char* name, const char* metaName,
*/ */
UAVObjHandle UAVObjGetByID(uint32_t id) UAVObjHandle UAVObjGetByID(uint32_t id)
{ {
ObjectList* objEntry; ObjectList *objEntry;
// Get lock // Get lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Look for object // Look for object
LL_FOREACH(objList, objEntry) LL_FOREACH(objList, objEntry) {
{ if (objEntry->id == id) {
if (objEntry->id == id) // Release lock
{ xSemaphoreGiveRecursive(mutex);
// Release lock // Done, object found
xSemaphoreGiveRecursive(mutex); return (UAVObjHandle) objEntry;
// Done, object found }
return (UAVObjHandle)objEntry; }
}
}
// Object not found, release lock and return error // Object not found, release lock and return error
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return NULL; return NULL;
} }
/** /**
@ -281,28 +287,27 @@ UAVObjHandle UAVObjGetByID(uint32_t id)
* \param[in] name The name of the object * \param[in] name The name of the object
* \return The object or NULL if not found. * \return The object or NULL if not found.
*/ */
UAVObjHandle UAVObjGetByName(char* name) UAVObjHandle UAVObjGetByName(char *name)
{ {
ObjectList* objEntry; ObjectList *objEntry;
// Get lock // Get lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Look for object // Look for object
LL_FOREACH(objList, objEntry) LL_FOREACH(objList, objEntry) {
{ if (objEntry->name != NULL
if (objEntry->name != NULL && strcmp(objEntry->name, name) == 0) && strcmp(objEntry->name, name) == 0) {
{ // Release lock
// Release lock xSemaphoreGiveRecursive(mutex);
xSemaphoreGiveRecursive(mutex); // Done, object found
// Done, object found return (UAVObjHandle) objEntry;
return (UAVObjHandle)objEntry; }
} }
}
// Object not found, release lock and return error // Object not found, release lock and return error
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return NULL; return NULL;
} }
/** /**
@ -312,7 +317,7 @@ UAVObjHandle UAVObjGetByName(char* name)
*/ */
uint32_t UAVObjGetID(UAVObjHandle obj) uint32_t UAVObjGetID(UAVObjHandle obj)
{ {
return ((ObjectList*)obj)->id; return ((ObjectList *) obj)->id;
} }
/** /**
@ -320,9 +325,9 @@ uint32_t UAVObjGetID(UAVObjHandle obj)
* \param[in] obj The object handle * \param[in] obj The object handle
* \return The object's name * \return The object's name
*/ */
const char* UAVObjGetName(UAVObjHandle obj) const char *UAVObjGetName(UAVObjHandle obj)
{ {
return ((ObjectList*)obj)->name; return ((ObjectList *) obj)->name;
} }
/** /**
@ -332,7 +337,7 @@ const char* UAVObjGetName(UAVObjHandle obj)
*/ */
uint32_t UAVObjGetNumBytes(UAVObjHandle obj) uint32_t UAVObjGetNumBytes(UAVObjHandle obj)
{ {
return ((ObjectList*)obj)->numBytes; return ((ObjectList *) obj)->numBytes;
} }
/** /**
@ -344,7 +349,7 @@ uint32_t UAVObjGetNumBytes(UAVObjHandle obj)
*/ */
UAVObjHandle UAVObjGetLinkedObj(UAVObjHandle obj) UAVObjHandle UAVObjGetLinkedObj(UAVObjHandle obj)
{ {
return (UAVObjHandle)(((ObjectList*)obj)->linkedObj); return (UAVObjHandle) (((ObjectList *) obj)->linkedObj);
} }
/** /**
@ -354,11 +359,11 @@ UAVObjHandle UAVObjGetLinkedObj(UAVObjHandle obj)
*/ */
uint16_t UAVObjGetNumInstances(UAVObjHandle obj) uint16_t UAVObjGetNumInstances(UAVObjHandle obj)
{ {
uint32_t numInstances; uint32_t numInstances;
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
numInstances = ((ObjectList*)obj)->numInstances; numInstances = ((ObjectList *) obj)->numInstances;
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return numInstances; return numInstances;
} }
/** /**
@ -366,32 +371,29 @@ uint16_t UAVObjGetNumInstances(UAVObjHandle obj)
* \param[in] obj The object handle * \param[in] obj The object handle
* \return The instance ID or 0 if an error * \return The instance ID or 0 if an error
*/ */
uint16_t UAVObjCreateInstance(UAVObjHandle obj, UAVObjInitializeCallback initCb) uint16_t UAVObjCreateInstance(UAVObjHandle obj,
UAVObjInitializeCallback initCb)
{ {
ObjectList* objEntry; ObjectList *objEntry;
ObjectInstList* instEntry; ObjectInstList *instEntry;
// Lock // Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Create new instance // Create new instance
objEntry = (ObjectList*)obj; objEntry = (ObjectList *) obj;
instEntry = createInstance(objEntry, objEntry->numInstances); instEntry = createInstance(objEntry, objEntry->numInstances);
if ( instEntry == NULL ) if (instEntry == NULL) {
{ xSemaphoreGiveRecursive(mutex);
xSemaphoreGiveRecursive(mutex); return -1;
return -1; }
} // Initialize instance data
if (initCb != NULL) {
// Initialize instance data initCb(obj, instEntry->instId);
if ( initCb != NULL ) }
{ // Unlock
initCb(obj, instEntry->instId); xSemaphoreGiveRecursive(mutex);
} return instEntry->instId;
// Unlock
xSemaphoreGiveRecursive(mutex);
return instEntry->instId;
} }
/** /**
@ -401,7 +403,7 @@ uint16_t UAVObjCreateInstance(UAVObjHandle obj, UAVObjInitializeCallback initCb)
*/ */
int32_t UAVObjIsSingleInstance(UAVObjHandle obj) int32_t UAVObjIsSingleInstance(UAVObjHandle obj)
{ {
return ((ObjectList*)obj)->isSingleInstance; return ((ObjectList *) obj)->isSingleInstance;
} }
/** /**
@ -411,7 +413,7 @@ int32_t UAVObjIsSingleInstance(UAVObjHandle obj)
*/ */
int32_t UAVObjIsMetaobject(UAVObjHandle obj) int32_t UAVObjIsMetaobject(UAVObjHandle obj)
{ {
return ((ObjectList*)obj)->isMetaobject; return ((ObjectList *) obj)->isMetaobject;
} }
/** /**
@ -421,7 +423,7 @@ int32_t UAVObjIsMetaobject(UAVObjHandle obj)
*/ */
int32_t UAVObjIsSettings(UAVObjHandle obj) int32_t UAVObjIsSettings(UAVObjHandle obj)
{ {
return ((ObjectList*)obj)->isSettings; return ((ObjectList *) obj)->isSettings;
} }
/** /**
@ -431,41 +433,39 @@ int32_t UAVObjIsSettings(UAVObjHandle obj)
* \param[in] dataIn The byte array * \param[in] dataIn The byte array
* \return 0 if success or -1 if failure * \return 0 if success or -1 if failure
*/ */
int32_t UAVObjUnpack(UAVObjHandle obj, uint16_t instId, const uint8_t* dataIn) int32_t UAVObjUnpack(UAVObjHandle obj, uint16_t instId,
const uint8_t * dataIn)
{ {
ObjectList* objEntry; ObjectList *objEntry;
ObjectInstList* instEntry; ObjectInstList *instEntry;
// Lock // Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Cast handle to object // Cast handle to object
objEntry = (ObjectList*)obj; objEntry = (ObjectList *) obj;
// Get the instance // Get the instance
instEntry = getInstance(objEntry, instId); instEntry = getInstance(objEntry, instId);
// If the instance does not exist create it and any other instances before it // If the instance does not exist create it and any other instances before it
if ( instEntry == NULL ) if (instEntry == NULL) {
{ instEntry = createInstance(objEntry, instId);
instEntry = createInstance(objEntry, instId); if (instEntry == NULL) {
if ( instEntry == NULL ) // Error, unlock and return
{ xSemaphoreGiveRecursive(mutex);
// Error, unlock and return return -1;
xSemaphoreGiveRecursive(mutex); }
return -1; }
} // Set the data
} memcpy(instEntry->data, dataIn, objEntry->numBytes);
// Set the data // Fire event
memcpy(instEntry->data, dataIn, objEntry->numBytes); sendEvent(objEntry, instId, EV_UNPACKED);
// Fire event // Unlock
sendEvent(objEntry, instId, EV_UNPACKED); xSemaphoreGiveRecursive(mutex);
return 0;
// Unlock
xSemaphoreGiveRecursive(mutex);
return 0;
} }
/** /**
@ -475,32 +475,30 @@ int32_t UAVObjUnpack(UAVObjHandle obj, uint16_t instId, const uint8_t* dataIn)
* \param[out] dataOut The byte array * \param[out] dataOut The byte array
* \return 0 if success or -1 if failure * \return 0 if success or -1 if failure
*/ */
int32_t UAVObjPack(UAVObjHandle obj, uint16_t instId, uint8_t* dataOut) int32_t UAVObjPack(UAVObjHandle obj, uint16_t instId, uint8_t * dataOut)
{ {
ObjectList* objEntry; ObjectList *objEntry;
ObjectInstList* instEntry; ObjectInstList *instEntry;
// Lock // Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Cast handle to object // Cast handle to object
objEntry = (ObjectList*)obj; objEntry = (ObjectList *) obj;
// Get the instance // Get the instance
instEntry = getInstance(objEntry, instId); instEntry = getInstance(objEntry, instId);
if ( instEntry == NULL ) if (instEntry == NULL) {
{ // Error, unlock and return
// Error, unlock and return xSemaphoreGiveRecursive(mutex);
xSemaphoreGiveRecursive(mutex); return -1;
return -1; }
} // Pack data
memcpy(dataOut, instEntry->data, objEntry->numBytes);
// Pack data // Unlock
memcpy(dataOut, instEntry->data, objEntry->numBytes); xSemaphoreGiveRecursive(mutex);
return 0;
// Unlock
xSemaphoreGiveRecursive(mutex);
return 0;
} }
/** /**
@ -512,64 +510,52 @@ int32_t UAVObjPack(UAVObjHandle obj, uint16_t instId, uint8_t* dataOut)
* @param[in] file File to append to * @param[in] file File to append to
* @return 0 if success or -1 if failure * @return 0 if success or -1 if failure
*/ */
int32_t UAVObjSaveToFile(UAVObjHandle obj, uint16_t instId, FILEINFO* file) int32_t UAVObjSaveToFile(UAVObjHandle obj, uint16_t instId,
FILEINFO * file)
{ {
#if defined(PIOS_INCLUDE_SDCARD) #if defined(PIOS_INCLUDE_SDCARD)
uint32_t bytesWritten; uint32_t bytesWritten;
ObjectList* objEntry; ObjectList *objEntry;
ObjectInstList* instEntry; ObjectInstList *instEntry;
// Check for file system availability // Check for file system availability
if ( PIOS_SDCARD_IsMounted() == 0 ) if (PIOS_SDCARD_IsMounted() == 0) {
{ return -1;
return -1; }
} // Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Lock // Cast to object
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); objEntry = (ObjectList *) obj;
// Cast to object // Get the instance information
objEntry = (ObjectList*)obj; instEntry = getInstance(objEntry, instId);
if (instEntry == NULL) {
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Write the object ID
PIOS_FWRITE(file, &objEntry->id, sizeof(objEntry->id),
&bytesWritten);
// Get the instance information // Write the instance ID
instEntry = getInstance(objEntry, instId); if (!objEntry->isSingleInstance) {
if ( instEntry == NULL ) PIOS_FWRITE(file, &instEntry->instId,
{ sizeof(instEntry->instId), &bytesWritten);
xSemaphoreGiveRecursive(mutex); }
return -1; // Write the data and check that the write was successful
} PIOS_FWRITE(file, instEntry->data, objEntry->numBytes,
&bytesWritten);
// Write the object ID if (bytesWritten != objEntry->numBytes) {
PIOS_FWRITE(file,&objEntry->id,sizeof(objEntry->id),&bytesWritten); xSemaphoreGiveRecursive(mutex);
return -1;
// Write the instance ID }
if (!objEntry->isSingleInstance) // Done
{ xSemaphoreGiveRecursive(mutex);
PIOS_FWRITE(file,&instEntry->instId,sizeof(instEntry->instId),&bytesWritten);
}
// Write the data and check that the write was successful
PIOS_FWRITE(file,instEntry->data,objEntry->numBytes,&bytesWritten);
if ( bytesWritten != objEntry->numBytes )
{
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Done
xSemaphoreGiveRecursive(mutex);
#endif /* PIOS_INCLUDE_SDCARD */ #endif /* PIOS_INCLUDE_SDCARD */
return 0; return 0;
} }
struct fileHeader {
uint32_t id;
uint16_t instId;
uint16_t size;
} __attribute__((packed));
#define FLASH_MASK 0x001ff000 /* Select a sector */
/** /**
* Save the data of the specified object to the file system (SD card). * Save the data of the specified object to the file system (SD card).
* If the object contains multiple instances, all of them will be saved. * If the object contains multiple instances, all of them will be saved.
@ -583,71 +569,56 @@ struct fileHeader {
int32_t UAVObjSave(UAVObjHandle obj, uint16_t instId) int32_t UAVObjSave(UAVObjHandle obj, uint16_t instId)
{ {
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) #if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
ObjectList* objEntry = (ObjectList*)obj; ObjectList *objEntry = (ObjectList *) obj;
if(objEntry == NULL) if (objEntry == NULL)
return -1; return -1;
ObjectInstList* instEntry = getInstance(objEntry, instId); ObjectInstList *instEntry = getInstance(objEntry, instId);
if(instEntry == NULL) if (instEntry == NULL)
return -1; return -1;
if(instEntry->data == NULL) if (instEntry->data == NULL)
return -1; return -1;
if (PIOS_FLASHFS_ObjSave(obj, instId, instEntry->data) != 0)
struct fileHeader header = { return -1;
.id = objEntry->id,
.instId = instId,
.size = objEntry->numBytes
};
uint32_t addr = (objEntry->id & FLASH_MASK);
PIOS_Flash_W25X_EraseSector(addr);
PIOS_Flash_W25X_WriteData(addr, (uint8_t *) &header, sizeof(header));
PIOS_Flash_W25X_WriteData(addr + sizeof(header), instEntry->data,objEntry->numBytes);
#endif #endif
#if defined(PIOS_INCLUDE_SDCARD) #if defined(PIOS_INCLUDE_SDCARD)
FILEINFO file; FILEINFO file;
ObjectList* objEntry; ObjectList *objEntry;
uint8_t filename[14]; uint8_t filename[14];
// Check for file system availability // Check for file system availability
if ( PIOS_SDCARD_IsMounted() == 0 ) if (PIOS_SDCARD_IsMounted() == 0) {
{ return -1;
return -1; }
} // Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Lock // Cast to object
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); objEntry = (ObjectList *) obj;
// Cast to object // Get filename
objEntry = (ObjectList*)obj; objectFilename(objEntry, filename);
// Get filename // Open file
objectFilename(objEntry, filename); if (PIOS_FOPEN_WRITE(filename, file)) {
xSemaphoreGiveRecursive(mutex);
// Open file return -1;
if ( PIOS_FOPEN_WRITE(filename,file) ) }
{ // Append object
xSemaphoreGiveRecursive(mutex); if (UAVObjSaveToFile(obj, instId, &file) == -1) {
return -1; PIOS_FCLOSE(file);
} xSemaphoreGiveRecursive(mutex);
return -1;
// Append object }
if ( UAVObjSaveToFile(obj, instId, &file) == -1 ) // Done, close file and unlock
{ PIOS_FCLOSE(file);
PIOS_FCLOSE(file); xSemaphoreGiveRecursive(mutex);
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Done, close file and unlock
PIOS_FCLOSE(file);
xSemaphoreGiveRecursive(mutex);
#endif /* PIOS_INCLUDE_SDCARD */ #endif /* PIOS_INCLUDE_SDCARD */
return 0; return 0;
} }
/** /**
@ -655,82 +626,71 @@ int32_t UAVObjSave(UAVObjHandle obj, uint16_t instId)
* @param[in] file File to read from * @param[in] file File to read from
* @return The handle of the object loaded or NULL if a failure * @return The handle of the object loaded or NULL if a failure
*/ */
UAVObjHandle UAVObjLoadFromFile(FILEINFO* file) UAVObjHandle UAVObjLoadFromFile(FILEINFO * file)
{ {
#if defined(PIOS_INCLUDE_SDCARD) #if defined(PIOS_INCLUDE_SDCARD)
uint32_t bytesRead; uint32_t bytesRead;
ObjectList* objEntry; ObjectList *objEntry;
ObjectInstList* instEntry; ObjectInstList *instEntry;
uint32_t objId; uint32_t objId;
uint16_t instId; uint16_t instId;
UAVObjHandle obj; UAVObjHandle obj;
// Check for file system availability // Check for file system availability
if ( PIOS_SDCARD_IsMounted() == 0 ) if (PIOS_SDCARD_IsMounted() == 0) {
{ return NULL;
return NULL; }
} // Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Lock // Read the object ID
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); if (PIOS_FREAD(file, &objId, sizeof(objId), &bytesRead)) {
xSemaphoreGiveRecursive(mutex);
return NULL;
}
// Get the object
obj = UAVObjGetByID(objId);
if (obj == 0) {
xSemaphoreGiveRecursive(mutex);
return NULL;
}
objEntry = (ObjectList *) obj;
// Read the object ID // Get the instance ID
if ( PIOS_FREAD(file,&objId,sizeof(objId),&bytesRead) ) instId = 0;
{ if (!objEntry->isSingleInstance) {
xSemaphoreGiveRecursive(mutex); if (PIOS_FREAD
return NULL; (file, &instId, sizeof(instId), &bytesRead)) {
} xSemaphoreGiveRecursive(mutex);
return NULL;
}
}
// Get the instance information
instEntry = getInstance(objEntry, instId);
// Get the object // If the instance does not exist create it and any other instances before it
obj = UAVObjGetByID(objId); if (instEntry == NULL) {
if ( obj == 0 ) instEntry = createInstance(objEntry, instId);
{ if (instEntry == NULL) {
xSemaphoreGiveRecursive(mutex); // Error, unlock and return
return NULL; xSemaphoreGiveRecursive(mutex);
} return NULL;
objEntry = (ObjectList*)obj; }
}
// Read the instance data
if (PIOS_FREAD
(file, instEntry->data, objEntry->numBytes, &bytesRead)) {
xSemaphoreGiveRecursive(mutex);
return NULL;
}
// Fire event
sendEvent(objEntry, instId, EV_UNPACKED);
// Get the instance ID // Unlock
instId = 0; xSemaphoreGiveRecursive(mutex);
if ( !objEntry->isSingleInstance ) return obj;
{
if ( PIOS_FREAD(file,&instId,sizeof(instId),&bytesRead) )
{
xSemaphoreGiveRecursive(mutex);
return NULL;
}
}
// Get the instance information
instEntry = getInstance(objEntry, instId);
// If the instance does not exist create it and any other instances before it
if ( instEntry == NULL )
{
instEntry = createInstance(objEntry, instId);
if ( instEntry == NULL )
{
// Error, unlock and return
xSemaphoreGiveRecursive(mutex);
return NULL;
}
}
// Read the instance data
if ( PIOS_FREAD(file,instEntry->data,objEntry->numBytes,&bytesRead) )
{
xSemaphoreGiveRecursive(mutex);
return NULL;
}
// Fire event
sendEvent(objEntry, instId, EV_UNPACKED);
// Unlock
xSemaphoreGiveRecursive(mutex);
return obj;
#else /* PIOS_INCLUDE_SDCARD */ #else /* PIOS_INCLUDE_SDCARD */
return NULL; return NULL;
#endif #endif
} }
@ -745,87 +705,70 @@ UAVObjHandle UAVObjLoadFromFile(FILEINFO* file)
int32_t UAVObjLoad(UAVObjHandle obj, uint16_t instId) int32_t UAVObjLoad(UAVObjHandle obj, uint16_t instId)
{ {
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) #if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
ObjectList* objEntry = (ObjectList*)obj; ObjectList *objEntry = (ObjectList *) obj;
if(objEntry == NULL) if (objEntry == NULL)
return -1; return -1;
ObjectInstList* instEntry = getInstance(objEntry, instId); ObjectInstList *instEntry = getInstance(objEntry, instId);
if(instEntry == NULL) if (instEntry == NULL)
return -1; return -1;
if(instEntry->data == NULL) if (instEntry->data == NULL)
return -1; return -1;
struct fileHeader header; // Fire event on success
uint32_t addr = (objEntry->id & FLASH_MASK); if (PIOS_FLASHFS_ObjLoad(obj, instId, instEntry->data) == 0)
sendEvent(objEntry, instId, EV_UNPACKED);
PIOS_Flash_W25X_ReadData(addr, (uint8_t *) &header, sizeof(header)); else
return -1;
if(header.id != objEntry->id)
return -1;
// Read the instance data
if (PIOS_Flash_W25X_ReadData(addr + sizeof(header) ,instEntry->data, objEntry->numBytes) != 0)
return -1;
// Fire event
sendEvent(objEntry, instId, EV_UNPACKED);
#endif #endif
#if defined(PIOS_INCLUDE_SDCARD) #if defined(PIOS_INCLUDE_SDCARD)
FILEINFO file; FILEINFO file;
ObjectList* objEntry; ObjectList *objEntry;
UAVObjHandle loadedObj; UAVObjHandle loadedObj;
ObjectList* loadedObjEntry; ObjectList *loadedObjEntry;
uint8_t filename[14]; uint8_t filename[14];
// Check for file system availability // Check for file system availability
if ( PIOS_SDCARD_IsMounted() == 0 ) if (PIOS_SDCARD_IsMounted() == 0) {
{ return -1;
return -1; }
} // Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Lock // Cast to object
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); objEntry = (ObjectList *) obj;
// Cast to object // Get filename
objEntry = (ObjectList*)obj; objectFilename(objEntry, filename);
// Get filename // Open file
objectFilename(objEntry, filename); if (PIOS_FOPEN_READ(filename, file)) {
xSemaphoreGiveRecursive(mutex);
// Open file return -1;
if ( PIOS_FOPEN_READ(filename,file) ) }
{ // Load object
xSemaphoreGiveRecursive(mutex); loadedObj = UAVObjLoadFromFile(&file);
return -1; if (loadedObj == 0) {
} PIOS_FCLOSE(file);
xSemaphoreGiveRecursive(mutex);
// Load object return -1;
loadedObj = UAVObjLoadFromFile(&file); }
if (loadedObj == 0) // Check that the IDs match
{ loadedObjEntry = (ObjectList *) loadedObj;
PIOS_FCLOSE(file); if (loadedObjEntry->id != objEntry->id) {
xSemaphoreGiveRecursive(mutex); PIOS_FCLOSE(file);
return -1; xSemaphoreGiveRecursive(mutex);
} return -1;
}
// Check that the IDs match // Done, close file and unlock
loadedObjEntry = (ObjectList*)loadedObj; PIOS_FCLOSE(file);
if ( loadedObjEntry->id != objEntry->id ) xSemaphoreGiveRecursive(mutex);
{
PIOS_FCLOSE(file);
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Done, close file and unlock
PIOS_FCLOSE(file);
xSemaphoreGiveRecursive(mutex);
#endif /* PIOS_INCLUDE_SDCARD */ #endif /* PIOS_INCLUDE_SDCARD */
return 0; return 0;
} }
/** /**
@ -837,40 +780,32 @@ int32_t UAVObjLoad(UAVObjHandle obj, uint16_t instId)
int32_t UAVObjDelete(UAVObjHandle obj, uint16_t instId) int32_t UAVObjDelete(UAVObjHandle obj, uint16_t instId)
{ {
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) #if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
ObjectList* objEntry = (ObjectList*)obj; PIOS_FLASHFS_ObjDelete(obj, instId);
if(objEntry == NULL)
return -1;
uint32_t addr = (objEntry->id & FLASH_MASK);
PIOS_Flash_W25X_EraseSector(addr);
#endif #endif
#if defined(PIOS_INCLUDE_SDCARD) #if defined(PIOS_INCLUDE_SDCARD)
ObjectList* objEntry; ObjectList *objEntry;
uint8_t filename[14]; uint8_t filename[14];
// Check for file system availability // Check for file system availability
if ( PIOS_SDCARD_IsMounted() == 0 ) if (PIOS_SDCARD_IsMounted() == 0) {
{ return -1;
return -1; }
} // Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Lock // Cast to object
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); objEntry = (ObjectList *) obj;
// Cast to object // Get filename
objEntry = (ObjectList*)obj; objectFilename(objEntry, filename);
// Get filename // Delete file
objectFilename(objEntry, filename); PIOS_FUNLINK(filename);
// Delete file // Done
PIOS_FUNLINK(filename); xSemaphoreGiveRecursive(mutex);
// Done
xSemaphoreGiveRecursive(mutex);
#endif /* PIOS_INCLUDE_SDCARD */ #endif /* PIOS_INCLUDE_SDCARD */
return 0; return 0;
} }
/** /**
@ -879,29 +814,27 @@ int32_t UAVObjDelete(UAVObjHandle obj, uint16_t instId)
*/ */
int32_t UAVObjSaveSettings() int32_t UAVObjSaveSettings()
{ {
ObjectList* objEntry; ObjectList *objEntry;
// Get lock // Get lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Save all settings objects // Save all settings objects
LL_FOREACH(objList, objEntry) LL_FOREACH(objList, objEntry) {
{ // Check if this is a settings object
// Check if this is a settings object if (objEntry->isSettings) {
if ( objEntry->isSettings ) // Save object
{ if (UAVObjSave((UAVObjHandle) objEntry, 0) ==
// Save object -1) {
if ( UAVObjSave( (UAVObjHandle)objEntry, 0 ) == -1 ) xSemaphoreGiveRecursive(mutex);
{ return -1;
xSemaphoreGiveRecursive(mutex); }
return -1; }
} }
}
}
// Done // Done
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return 0; return 0;
} }
/** /**
@ -910,29 +843,27 @@ int32_t UAVObjSaveSettings()
*/ */
int32_t UAVObjLoadSettings() int32_t UAVObjLoadSettings()
{ {
ObjectList* objEntry; ObjectList *objEntry;
// Get lock // Get lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Load all settings objects // Load all settings objects
LL_FOREACH(objList, objEntry) LL_FOREACH(objList, objEntry) {
{ // Check if this is a settings object
// Check if this is a settings object if (objEntry->isSettings) {
if ( objEntry->isSettings ) // Load object
{ if (UAVObjLoad((UAVObjHandle) objEntry, 0) ==
// Load object -1) {
if ( UAVObjLoad( (UAVObjHandle)objEntry, 0 ) == -1 ) xSemaphoreGiveRecursive(mutex);
{ return -1;
xSemaphoreGiveRecursive(mutex); }
return -1; }
} }
}
}
// Done // Done
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return 0; return 0;
} }
/** /**
@ -941,29 +872,27 @@ int32_t UAVObjLoadSettings()
*/ */
int32_t UAVObjDeleteSettings() int32_t UAVObjDeleteSettings()
{ {
ObjectList* objEntry; ObjectList *objEntry;
// Get lock // Get lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Save all settings objects // Save all settings objects
LL_FOREACH(objList, objEntry) LL_FOREACH(objList, objEntry) {
{ // Check if this is a settings object
// Check if this is a settings object if (objEntry->isSettings) {
if ( objEntry->isSettings ) // Save object
{ if (UAVObjDelete((UAVObjHandle) objEntry, 0)
// Save object == -1) {
if ( UAVObjDelete( (UAVObjHandle)objEntry, 0 ) == -1 ) xSemaphoreGiveRecursive(mutex);
{ return -1;
xSemaphoreGiveRecursive(mutex); }
return -1; }
} }
}
}
// Done // Done
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return 0; return 0;
} }
/** /**
@ -972,29 +901,27 @@ int32_t UAVObjDeleteSettings()
*/ */
int32_t UAVObjSaveMetaobjects() int32_t UAVObjSaveMetaobjects()
{ {
ObjectList* objEntry; ObjectList *objEntry;
// Get lock // Get lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Save all settings objects // Save all settings objects
LL_FOREACH(objList, objEntry) LL_FOREACH(objList, objEntry) {
{ // Check if this is a settings object
// Check if this is a settings object if (objEntry->isMetaobject) {
if ( objEntry->isMetaobject ) // Save object
{ if (UAVObjSave((UAVObjHandle) objEntry, 0) ==
// Save object -1) {
if ( UAVObjSave( (UAVObjHandle)objEntry, 0 ) == -1 ) xSemaphoreGiveRecursive(mutex);
{ return -1;
xSemaphoreGiveRecursive(mutex); }
return -1; }
} }
}
}
// Done // Done
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return 0; return 0;
} }
/** /**
@ -1003,29 +930,27 @@ int32_t UAVObjSaveMetaobjects()
*/ */
int32_t UAVObjLoadMetaobjects() int32_t UAVObjLoadMetaobjects()
{ {
ObjectList* objEntry; ObjectList *objEntry;
// Get lock // Get lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Load all settings objects // Load all settings objects
LL_FOREACH(objList, objEntry) LL_FOREACH(objList, objEntry) {
{ // Check if this is a settings object
// Check if this is a settings object if (objEntry->isMetaobject) {
if ( objEntry->isMetaobject ) // Load object
{ if (UAVObjLoad((UAVObjHandle) objEntry, 0) ==
// Load object -1) {
if ( UAVObjLoad( (UAVObjHandle)objEntry, 0 ) == -1 ) xSemaphoreGiveRecursive(mutex);
{ return -1;
xSemaphoreGiveRecursive(mutex); }
return -1; }
} }
}
}
// Done // Done
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return 0; return 0;
} }
/** /**
@ -1034,29 +959,27 @@ int32_t UAVObjLoadMetaobjects()
*/ */
int32_t UAVObjDeleteMetaobjects() int32_t UAVObjDeleteMetaobjects()
{ {
ObjectList* objEntry; ObjectList *objEntry;
// Get lock // Get lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Load all settings objects // Load all settings objects
LL_FOREACH(objList, objEntry) LL_FOREACH(objList, objEntry) {
{ // Check if this is a settings object
// Check if this is a settings object if (objEntry->isMetaobject) {
if ( objEntry->isMetaobject ) // Load object
{ if (UAVObjDelete((UAVObjHandle) objEntry, 0)
// Load object == -1) {
if ( UAVObjDelete( (UAVObjHandle)objEntry, 0 ) == -1 ) xSemaphoreGiveRecursive(mutex);
{ return -1;
xSemaphoreGiveRecursive(mutex); }
return -1; }
} }
}
}
// Done // Done
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return 0; return 0;
} }
/** /**
@ -1065,9 +988,9 @@ int32_t UAVObjDeleteMetaobjects()
* \param[in] dataIn The object's data structure * \param[in] dataIn The object's data structure
* \return 0 if success or -1 if failure * \return 0 if success or -1 if failure
*/ */
int32_t UAVObjSetData(UAVObjHandle obj, const void* dataIn) int32_t UAVObjSetData(UAVObjHandle obj, const void *dataIn)
{ {
return UAVObjSetInstanceData(obj, 0, dataIn); return UAVObjSetInstanceData(obj, 0, dataIn);
} }
/** /**
@ -1076,9 +999,9 @@ int32_t UAVObjSetData(UAVObjHandle obj, const void* dataIn)
* \param[out] dataOut The object's data structure * \param[out] dataOut The object's data structure
* \return 0 if success or -1 if failure * \return 0 if success or -1 if failure
*/ */
int32_t UAVObjGetData(UAVObjHandle obj, void* dataOut) int32_t UAVObjGetData(UAVObjHandle obj, void *dataOut)
{ {
return UAVObjGetInstanceData(obj, 0, dataOut); return UAVObjGetInstanceData(obj, 0, dataOut);
} }
/** /**
@ -1088,47 +1011,45 @@ int32_t UAVObjGetData(UAVObjHandle obj, void* dataOut)
* \param[in] dataIn The object's data structure * \param[in] dataIn The object's data structure
* \return 0 if success or -1 if failure * \return 0 if success or -1 if failure
*/ */
int32_t UAVObjSetInstanceData(UAVObjHandle obj, uint16_t instId, const void* dataIn) int32_t UAVObjSetInstanceData(UAVObjHandle obj, uint16_t instId,
const void *dataIn)
{ {
ObjectList* objEntry; ObjectList *objEntry;
ObjectInstList* instEntry; ObjectInstList *instEntry;
UAVObjMetadata* mdata; UAVObjMetadata *mdata;
// Lock // Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Cast to object info // Cast to object info
objEntry = (ObjectList*)obj; objEntry = (ObjectList *) obj;
// Check access level // Check access level
if ( !objEntry->isMetaobject ) if (!objEntry->isMetaobject) {
{ mdata =
mdata = (UAVObjMetadata*)(objEntry->linkedObj->instances.data); (UAVObjMetadata *) (objEntry->linkedObj->instances.
if ( mdata->access == ACCESS_READONLY ) data);
{ if (mdata->access == ACCESS_READONLY) {
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return -1; return -1;
} }
} }
// Get instance information
instEntry = getInstance(objEntry, instId);
if (instEntry == NULL) {
// Error, unlock and return
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Set data
memcpy(instEntry->data, dataIn, objEntry->numBytes);
// Get instance information // Fire event
instEntry = getInstance(objEntry, instId); sendEvent(objEntry, instId, EV_UPDATED);
if ( instEntry == NULL )
{
// Error, unlock and return
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Set data // Unlock
memcpy(instEntry->data, dataIn, objEntry->numBytes); xSemaphoreGiveRecursive(mutex);
return 0;
// Fire event
sendEvent(objEntry, instId, EV_UPDATED);
// Unlock
xSemaphoreGiveRecursive(mutex);
return 0;
} }
/** /**
@ -1138,32 +1059,31 @@ int32_t UAVObjSetInstanceData(UAVObjHandle obj, uint16_t instId, const void* dat
* \param[out] dataOut The object's data structure * \param[out] dataOut The object's data structure
* \return 0 if success or -1 if failure * \return 0 if success or -1 if failure
*/ */
int32_t UAVObjGetInstanceData(UAVObjHandle obj, uint16_t instId, void* dataOut) int32_t UAVObjGetInstanceData(UAVObjHandle obj, uint16_t instId,
void *dataOut)
{ {
ObjectList* objEntry; ObjectList *objEntry;
ObjectInstList* instEntry; ObjectInstList *instEntry;
// Lock // Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Cast to object info // Cast to object info
objEntry = (ObjectList*)obj; objEntry = (ObjectList *) obj;
// Get instance information // Get instance information
instEntry = getInstance(objEntry, instId); instEntry = getInstance(objEntry, instId);
if ( instEntry == NULL ) if (instEntry == NULL) {
{ // Error, unlock and return
// Error, unlock and return xSemaphoreGiveRecursive(mutex);
xSemaphoreGiveRecursive(mutex); return -1;
return -1; }
} // Set data
memcpy(dataOut, instEntry->data, objEntry->numBytes);
// Set data // Unlock
memcpy(dataOut, instEntry->data, objEntry->numBytes); xSemaphoreGiveRecursive(mutex);
return 0;
// Unlock
xSemaphoreGiveRecursive(mutex);
return 0;
} }
/** /**
@ -1172,27 +1092,25 @@ int32_t UAVObjGetInstanceData(UAVObjHandle obj, uint16_t instId, void* dataOut)
* \param[in] dataIn The object's metadata structure * \param[in] dataIn The object's metadata structure
* \return 0 if success or -1 if failure * \return 0 if success or -1 if failure
*/ */
int32_t UAVObjSetMetadata(UAVObjHandle obj, const UAVObjMetadata* dataIn) int32_t UAVObjSetMetadata(UAVObjHandle obj, const UAVObjMetadata * dataIn)
{ {
ObjectList* objEntry; ObjectList *objEntry;
// Lock // Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Set metadata (metadata of metaobjects can not be modified) // Set metadata (metadata of metaobjects can not be modified)
objEntry = (ObjectList*)obj; objEntry = (ObjectList *) obj;
if (!objEntry->isMetaobject) if (!objEntry->isMetaobject) {
{ UAVObjSetData((UAVObjHandle) objEntry->linkedObj,
UAVObjSetData((UAVObjHandle)objEntry->linkedObj, dataIn); dataIn);
} } else {
else return -1;
{ }
return -1;
}
// Unlock // Unlock
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return 0; return 0;
} }
/** /**
@ -1201,27 +1119,25 @@ int32_t UAVObjSetMetadata(UAVObjHandle obj, const UAVObjMetadata* dataIn)
* \param[out] dataOut The object's metadata structure * \param[out] dataOut The object's metadata structure
* \return 0 if success or -1 if failure * \return 0 if success or -1 if failure
*/ */
int32_t UAVObjGetMetadata(UAVObjHandle obj, UAVObjMetadata* dataOut) int32_t UAVObjGetMetadata(UAVObjHandle obj, UAVObjMetadata * dataOut)
{ {
ObjectList* objEntry; ObjectList *objEntry;
// Lock // Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Get metadata // Get metadata
objEntry = (ObjectList*)obj; objEntry = (ObjectList *) obj;
if (objEntry->isMetaobject) if (objEntry->isMetaobject) {
{ memcpy(dataOut, &defMetadata, sizeof(UAVObjMetadata));
memcpy(dataOut, &defMetadata, sizeof(UAVObjMetadata)); } else {
} UAVObjGetData((UAVObjHandle) objEntry->linkedObj,
else dataOut);
{ }
UAVObjGetData((UAVObjHandle)objEntry->linkedObj, dataOut);
}
// Unlock // Unlock
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return 0; return 0;
} }
/** /**
@ -1234,19 +1150,20 @@ int32_t UAVObjGetMetadata(UAVObjHandle obj, UAVObjMetadata* dataOut)
*/ */
int8_t UAVObjReadOnly(UAVObjHandle obj) int8_t UAVObjReadOnly(UAVObjHandle obj)
{ {
ObjectList* objEntry; ObjectList *objEntry;
UAVObjMetadata* mdata; UAVObjMetadata *mdata;
// Cast to object info // Cast to object info
objEntry = (ObjectList*)obj; objEntry = (ObjectList *) obj;
// Check access level // Check access level
if ( !objEntry->isMetaobject ) if (!objEntry->isMetaobject) {
{ mdata =
mdata = (UAVObjMetadata*)(objEntry->linkedObj->instances.data); (UAVObjMetadata *) (objEntry->linkedObj->instances.
return mdata->access == ACCESS_READONLY; data);
} return mdata->access == ACCESS_READONLY;
return -1; }
return -1;
} }
/** /**
@ -1257,13 +1174,14 @@ int8_t UAVObjReadOnly(UAVObjHandle obj)
* \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL) * \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL)
* \return 0 if success or -1 if failure * \return 0 if success or -1 if failure
*/ */
int32_t UAVObjConnectQueue(UAVObjHandle obj, xQueueHandle queue, int32_t eventMask) int32_t UAVObjConnectQueue(UAVObjHandle obj, xQueueHandle queue,
int32_t eventMask)
{ {
int32_t res; int32_t res;
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
res = connectObj(obj, queue, 0, eventMask); res = connectObj(obj, queue, 0, eventMask);
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return res; return res;
} }
/** /**
@ -1274,11 +1192,11 @@ int32_t UAVObjConnectQueue(UAVObjHandle obj, xQueueHandle queue, int32_t eventMa
*/ */
int32_t UAVObjDisconnectQueue(UAVObjHandle obj, xQueueHandle queue) int32_t UAVObjDisconnectQueue(UAVObjHandle obj, xQueueHandle queue)
{ {
int32_t res; int32_t res;
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
res = disconnectObj(obj, queue, 0); res = disconnectObj(obj, queue, 0);
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return res; return res;
} }
/** /**
@ -1289,13 +1207,14 @@ int32_t UAVObjDisconnectQueue(UAVObjHandle obj, xQueueHandle queue)
* \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL) * \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL)
* \return 0 if success or -1 if failure * \return 0 if success or -1 if failure
*/ */
int32_t UAVObjConnectCallback(UAVObjHandle obj, UAVObjEventCallback cb, int32_t eventMask) int32_t UAVObjConnectCallback(UAVObjHandle obj, UAVObjEventCallback cb,
int32_t eventMask)
{ {
int32_t res; int32_t res;
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
res = connectObj(obj, 0, cb, eventMask); res = connectObj(obj, 0, cb, eventMask);
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return res; return res;
} }
/** /**
@ -1306,14 +1225,13 @@ int32_t UAVObjConnectCallback(UAVObjHandle obj, UAVObjEventCallback cb, int32_t
*/ */
int32_t UAVObjDisconnectCallback(UAVObjHandle obj, UAVObjEventCallback cb) int32_t UAVObjDisconnectCallback(UAVObjHandle obj, UAVObjEventCallback cb)
{ {
int32_t res; int32_t res;
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
res = disconnectObj(obj, 0, cb); res = disconnectObj(obj, 0, cb);
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
return res; return res;
} }
/** /**
* Request an update of the object's data from the GCS. The call will not wait for the response, a EV_UPDATED event * Request an update of the object's data from the GCS. The call will not wait for the response, a EV_UPDATED event
* will be generated as soon as the object is updated. * will be generated as soon as the object is updated.
@ -1321,7 +1239,7 @@ int32_t UAVObjDisconnectCallback(UAVObjHandle obj, UAVObjEventCallback cb)
*/ */
void UAVObjRequestUpdate(UAVObjHandle obj) void UAVObjRequestUpdate(UAVObjHandle obj)
{ {
UAVObjRequestInstanceUpdate(obj, UAVOBJ_ALL_INSTANCES); UAVObjRequestInstanceUpdate(obj, UAVOBJ_ALL_INSTANCES);
} }
/** /**
@ -1332,9 +1250,9 @@ void UAVObjRequestUpdate(UAVObjHandle obj)
*/ */
void UAVObjRequestInstanceUpdate(UAVObjHandle obj, uint16_t instId) void UAVObjRequestInstanceUpdate(UAVObjHandle obj, uint16_t instId)
{ {
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
sendEvent((ObjectList*)obj, instId, EV_UPDATE_REQ); sendEvent((ObjectList *) obj, instId, EV_UPDATE_REQ);
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
} }
/** /**
@ -1343,7 +1261,7 @@ void UAVObjRequestInstanceUpdate(UAVObjHandle obj, uint16_t instId)
*/ */
void UAVObjUpdated(UAVObjHandle obj) void UAVObjUpdated(UAVObjHandle obj)
{ {
UAVObjInstanceUpdated(obj, UAVOBJ_ALL_INSTANCES); UAVObjInstanceUpdated(obj, UAVOBJ_ALL_INSTANCES);
} }
/** /**
@ -1353,9 +1271,9 @@ void UAVObjUpdated(UAVObjHandle obj)
*/ */
void UAVObjInstanceUpdated(UAVObjHandle obj, uint16_t instId) void UAVObjInstanceUpdated(UAVObjHandle obj, uint16_t instId)
{ {
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
sendEvent((ObjectList*)obj, instId, EV_UPDATED_MANUAL); sendEvent((ObjectList *) obj, instId, EV_UPDATED_MANUAL);
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
} }
/** /**
@ -1363,143 +1281,133 @@ void UAVObjInstanceUpdated(UAVObjHandle obj, uint16_t instId)
* \param iterator This function will be called once for each object, * \param iterator This function will be called once for each object,
* the object will be passed as a parameter * the object will be passed as a parameter
*/ */
void UAVObjIterate(void (*iterator)(UAVObjHandle obj)) void UAVObjIterate(void (*iterator) (UAVObjHandle obj))
{ {
ObjectList* objEntry; ObjectList *objEntry;
// Get lock // Get lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Iterate through the list and invoke iterator for each object // Iterate through the list and invoke iterator for each object
LL_FOREACH(objList, objEntry) LL_FOREACH(objList, objEntry) {
{ (*iterator) ((UAVObjHandle) objEntry);
(*iterator)((UAVObjHandle)objEntry); }
}
// Release lock // Release lock
xSemaphoreGiveRecursive(mutex); xSemaphoreGiveRecursive(mutex);
} }
/** /**
* Send an event to all event queues registered on the object. * Send an event to all event queues registered on the object.
*/ */
static int32_t sendEvent(ObjectList* obj, uint16_t instId, UAVObjEventType event) static int32_t sendEvent(ObjectList * obj, uint16_t instId,
UAVObjEventType event)
{ {
ObjectEventList* eventEntry; ObjectEventList *eventEntry;
UAVObjEvent msg; UAVObjEvent msg;
// Setup event // Setup event
msg.obj = (UAVObjHandle)obj; msg.obj = (UAVObjHandle) obj;
msg.event = event; msg.event = event;
msg.instId = instId; msg.instId = instId;
// Go through each object and push the event message in the queue (if event is activated for the queue) // Go through each object and push the event message in the queue (if event is activated for the queue)
LL_FOREACH(obj->events, eventEntry) LL_FOREACH(obj->events, eventEntry) {
{ if (eventEntry->eventMask == 0
if ( eventEntry->eventMask == 0 || (eventEntry->eventMask & event) != 0 ) || (eventEntry->eventMask & event) != 0) {
{ // Send to queue if a valid queue is registered
// Send to queue if a valid queue is registered if (eventEntry->queue != 0) {
if (eventEntry->queue != 0) if (xQueueSend(eventEntry->queue, &msg, 0) != pdTRUE) // will not block
{ {
if ( xQueueSend(eventEntry->queue, &msg, 0) != pdTRUE ) // will not block ++stats.eventErrors;
{ }
++stats.eventErrors; }
} // Invoke callback (from event task) if a valid one is registered
} if (eventEntry->cb != 0) {
// Invoke callback (from event task) if a valid one is registered if (EventCallbackDispatch(&msg, eventEntry->cb) != pdTRUE) // invoke callback from the event task, will not block
if (eventEntry->cb != 0) {
{ ++stats.eventErrors;
if ( EventCallbackDispatch(&msg, eventEntry->cb) != pdTRUE ) // invoke callback from the event task, will not block }
{ }
++stats.eventErrors; }
} }
}
}
}
// Done // Done
return 0; return 0;
} }
/** /**
* Create a new object instance, return the instance info or NULL if failure. * Create a new object instance, return the instance info or NULL if failure.
*/ */
static ObjectInstList* createInstance(ObjectList* obj, uint16_t instId) static ObjectInstList *createInstance(ObjectList * obj, uint16_t instId)
{ {
ObjectInstList* instEntry; ObjectInstList *instEntry;
int32_t n; int32_t n;
// For single instance objects, only instance zero is allowed // For single instance objects, only instance zero is allowed
if (obj->isSingleInstance && instId != 0) if (obj->isSingleInstance && instId != 0) {
{ return NULL;
return NULL; }
} // Make sure that the instance ID is within limits
if (instId >= UAVOBJ_MAX_INSTANCES) {
return NULL;
}
// Check if the instance already exists
if (getInstance(obj, instId) != NULL) {
return NULL;
}
// Create any missing instances (all instance IDs must be sequential)
for (n = obj->numInstances; n < instId; ++n) {
if (createInstance(obj, n) == NULL) {
return NULL;
}
}
// Make sure that the instance ID is within limits if (instId == 0) { /* Instance 0 ObjectInstList allocated with ObjectList element */
if (instId >= UAVOBJ_MAX_INSTANCES) instEntry = &obj->instances;
{ instEntry->data = pvPortMalloc(obj->numBytes);
return NULL; if (instEntry->data == NULL)
} return NULL;
memset(instEntry->data, 0, obj->numBytes);
instEntry->instId = instId;
} else {
// Create the actual instance
instEntry =
(ObjectInstList *)
pvPortMalloc(sizeof(ObjectInstList));
if (instEntry == NULL)
return NULL;
instEntry->data = pvPortMalloc(obj->numBytes);
if (instEntry->data == NULL)
return NULL;
memset(instEntry->data, 0, obj->numBytes);
instEntry->instId = instId;
LL_APPEND(obj->instances.next, instEntry);
}
++obj->numInstances;
// Check if the instance already exists // Fire event
if ( getInstance(obj, instId) != NULL ) UAVObjInstanceUpdated((UAVObjHandle) obj, instId);
{
return NULL;
}
// Create any missing instances (all instance IDs must be sequential) // Done
for (n = obj->numInstances; n < instId; ++n) return instEntry;
{
if ( createInstance(obj, n) == NULL )
{
return NULL;
}
}
if(instId == 0) /* Instance 0 ObjectInstList allocated with ObjectList element */
{
instEntry = &obj->instances;
instEntry->data = pvPortMalloc(obj->numBytes);
if (instEntry->data == NULL) return NULL;
memset(instEntry->data, 0, obj->numBytes);
instEntry->instId = instId;
} else
{
// Create the actual instance
instEntry = (ObjectInstList*)pvPortMalloc(sizeof(ObjectInstList));
if (instEntry == NULL) return NULL;
instEntry->data = pvPortMalloc(obj->numBytes);
if (instEntry->data == NULL) return NULL;
memset(instEntry->data, 0, obj->numBytes);
instEntry->instId = instId;
LL_APPEND(obj->instances.next, instEntry);
}
++obj->numInstances;
// Fire event
UAVObjInstanceUpdated((UAVObjHandle)obj, instId);
// Done
return instEntry;
} }
/** /**
* Get the instance information or NULL if the instance does not exist * Get the instance information or NULL if the instance does not exist
*/ */
static ObjectInstList* getInstance(ObjectList* obj, uint16_t instId) static ObjectInstList *getInstance(ObjectList * obj, uint16_t instId)
{ {
ObjectInstList* instEntry; ObjectInstList *instEntry;
// Look for specified instance ID // Look for specified instance ID
LL_FOREACH(&(obj->instances), instEntry) LL_FOREACH(&(obj->instances), instEntry) {
{ if (instEntry->instId == instId) {
if (instEntry->instId == instId) return instEntry;
{ }
return instEntry; }
} // If this point is reached then instance id was not found
} return NULL;
// If this point is reached then instance id was not found
return NULL;
} }
/** /**
@ -1510,36 +1418,35 @@ static ObjectInstList* getInstance(ObjectList* obj, uint16_t instId)
* \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL) * \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL)
* \return 0 if success or -1 if failure * \return 0 if success or -1 if failure
*/ */
static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue, UAVObjEventCallback cb, int32_t eventMask) static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue,
UAVObjEventCallback cb, int32_t eventMask)
{ {
ObjectEventList* eventEntry; ObjectEventList *eventEntry;
ObjectList* objEntry; ObjectList *objEntry;
// Check that the queue is not already connected, if it is simply update event mask // Check that the queue is not already connected, if it is simply update event mask
objEntry = (ObjectList*)obj; objEntry = (ObjectList *) obj;
LL_FOREACH(objEntry->events, eventEntry) LL_FOREACH(objEntry->events, eventEntry) {
{ if (eventEntry->queue == queue && eventEntry->cb == cb) {
if ( eventEntry->queue == queue && eventEntry->cb == cb ) // Already connected, update event mask and return
{ eventEntry->eventMask = eventMask;
// Already connected, update event mask and return return 0;
eventEntry->eventMask = eventMask; }
return 0; }
}
}
// Add queue to list // Add queue to list
eventEntry = (ObjectEventList*)pvPortMalloc(sizeof(ObjectEventList)); eventEntry =
if (eventEntry == NULL) (ObjectEventList *) pvPortMalloc(sizeof(ObjectEventList));
{ if (eventEntry == NULL) {
return -1; return -1;
} }
eventEntry->queue = queue; eventEntry->queue = queue;
eventEntry->cb = cb; eventEntry->cb = cb;
eventEntry->eventMask = eventMask; eventEntry->eventMask = eventMask;
LL_APPEND(objEntry->events, eventEntry); LL_APPEND(objEntry->events, eventEntry);
// Done // Done
return 0; return 0;
} }
/** /**
@ -1549,59 +1456,43 @@ static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue, UAVObjEventCallb
* \param[in] cb The event callback * \param[in] cb The event callback
* \return 0 if success or -1 if failure * \return 0 if success or -1 if failure
*/ */
static int32_t disconnectObj(UAVObjHandle obj, xQueueHandle queue, UAVObjEventCallback cb) static int32_t disconnectObj(UAVObjHandle obj, xQueueHandle queue,
UAVObjEventCallback cb)
{ {
ObjectEventList* eventEntry; ObjectEventList *eventEntry;
ObjectList* objEntry; ObjectList *objEntry;
// Find queue and remove it // Find queue and remove it
objEntry = (ObjectList*)obj; objEntry = (ObjectList *) obj;
LL_FOREACH(objEntry->events, eventEntry) LL_FOREACH(objEntry->events, eventEntry) {
{ if ((eventEntry->queue == queue
if ( ( eventEntry->queue == queue && eventEntry->cb == cb ) ) && eventEntry->cb == cb)) {
{ LL_DELETE(objEntry->events, eventEntry);
LL_DELETE(objEntry->events, eventEntry); vPortFree(eventEntry);
vPortFree(eventEntry); return 0;
return 0; }
} }
}
// If this point is reached the queue was not found // If this point is reached the queue was not found
return -1; return -1;
} }
#if defined(PIOS_INCLUDE_SDCARD) #if defined(PIOS_INCLUDE_SDCARD)
/** /**
* Wrapper for the sprintf function * Wrapper for the sprintf function
*/ */
static void customSPrintf(uint8_t* buffer, uint8_t* format, ...) static void customSPrintf(uint8_t * buffer, uint8_t * format, ...)
{ {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
vsprintf((char *)buffer, (char *)format, args); vsprintf((char *)buffer, (char *)format, args);
} }
/** /**
* Get an 8 character (plus extension) filename for the object. * Get an 8 character (plus extension) filename for the object.
*/ */
static void objectFilename(ObjectList* obj, uint8_t* filename) static void objectFilename(ObjectList * obj, uint8_t * filename)
{ {
customSPrintf(filename, (uint8_t*)"%X.obj", obj->id); customSPrintf(filename, (uint8_t *) "%X.obj", obj->id);
} }
#endif /* PIOS_INCLUDE_SDCARD */ #endif /* PIOS_INCLUDE_SDCARD */

View File

@ -21,6 +21,7 @@ alert
altitude altitude
amps amps
aquired aquired
armed
autonomous flight autonomous flight
battery battery
camera camera
@ -32,8 +33,10 @@ complete
connected connected
connection connection
control control
coptercontrol
critical critical
disabled disabled
disarmed
disconnected disconnected
feet feet
figure eight figure eight
@ -58,11 +61,13 @@ lost
low altitude low altitude
low battery low battery
low gps quality low gps quality
magic
manual flight manual flight
maxium maxium
meters meters
minimum minimum
mode mode
moved
MPH MPH
navigation navigation
OpenPilot OpenPilot
@ -122,8 +127,4 @@ hundread
thousand thousand
Upto: OpenPilot
critical
battery
point

View File

@ -1,5 +1,5 @@
[General] [General]
ViewGroup_Default=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\x5V\0\0\x2\x9a\0\0\0\x4\0\0\0\x4\0\0\0\x1\0\0\0\b\xfc\0\0\0\0) ViewGroup_Default=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\x5\xa0\0\0\x3/\0\0\0\x4\0\0\0\x4\0\0\0\x1\0\0\0\b\xfc\0\0\0\0)
[Workspace] [Workspace]
NumberOfWorkspaces=6 NumberOfWorkspaces=6
@ -7,7 +7,7 @@ Workspace1=Flight data
Icon1=:/core/images/ah.png Icon1=:/core/images/ah.png
Workspace2=Configuration Workspace2=Configuration
Icon2=:/core/images/config.png Icon2=:/core/images/config.png
Workspace3=Large Map Workspace3=Flight Planner
Icon3=:/core/images/world.png Icon3=:/core/images/world.png
Workspace4=Scopes Workspace4=Scopes
Icon4=:/core/images/scopes.png Icon4=:/core/images/scopes.png
@ -70,6 +70,7 @@ Mode1\splitter\side0\side1\splitterOrientation=1
Mode1\splitter\side0\side1\splitterSizes=304, 433 Mode1\splitter\side0\side1\splitterSizes=304, 433
Mode1\splitter\side0\side1\side0\type=uavGadget Mode1\splitter\side0\side1\side0\type=uavGadget
Mode1\splitter\side0\side1\side0\classId=ModelViewGadget Mode1\splitter\side0\side1\side0\classId=ModelViewGadget
Mode1\splitter\side0\side1\side0\gadget\activeConfiguration=Test Quad X
Mode1\splitter\side0\side1\side1\type=splitter Mode1\splitter\side0\side1\side1\type=splitter
Mode1\splitter\side0\side1\side1\splitterOrientation=2 Mode1\splitter\side0\side1\side1\splitterOrientation=2
Mode1\splitter\side0\side1\side1\splitterSizes=293, 64 Mode1\splitter\side0\side1\side1\splitterSizes=293, 64
@ -180,7 +181,15 @@ Mode2\splitter\side0\side1\side0\gadget\activeConfiguration=Telemetry RX Rate Ho
Mode2\splitter\side0\side1\side1\type=uavGadget Mode2\splitter\side0\side1\side1\type=uavGadget
Mode2\splitter\side0\side1\side1\classId=LineardialGadget Mode2\splitter\side0\side1\side1\classId=LineardialGadget
Mode2\splitter\side0\side1\side1\gadget\activeConfiguration=Telemetry TX Rate Horizontal Mode2\splitter\side0\side1\side1\gadget\activeConfiguration=Telemetry TX Rate Horizontal
Mode2\splitter\side1\type=uavGadget Mode2\splitter\side1\type=splitter
Mode2\splitter\side1\splitterOrientation=2
Mode2\splitter\side1\splitterSizes=426, 354
Mode2\splitter\side1\side0\type=uavGadget
Mode2\splitter\side1\side0\classId=UAVObjectBrowser
Mode2\splitter\side1\side0\gadget\activeConfiguration=default
Mode2\splitter\side1\side1\type=uavGadget
Mode2\splitter\side1\side1\classId=GCSControlGadget
Mode2\splitter\side1\side1\gadget\activeConfiguration=MS Sidewinder
Mode3\version=UAVGadgetManagerV1 Mode3\version=UAVGadgetManagerV1
Mode3\showToolbars=false Mode3\showToolbars=false
Mode3\splitter\type=splitter Mode3\splitter\type=splitter
@ -194,6 +203,7 @@ Mode3\splitter\side1\splitterOrientation=2
Mode3\splitter\side1\splitterSizes=395, 236 Mode3\splitter\side1\splitterSizes=395, 236
Mode3\splitter\side1\side0\type=uavGadget Mode3\splitter\side1\side0\type=uavGadget
Mode3\splitter\side1\side0\classId=ModelViewGadget Mode3\splitter\side1\side0\classId=ModelViewGadget
Mode3\splitter\side1\side0\gadget\activeConfiguration=Test Quad X
Mode3\splitter\side1\side1\type=splitter Mode3\splitter\side1\side1\type=splitter
Mode3\splitter\side1\side1\splitterOrientation=1 Mode3\splitter\side1\side1\splitterOrientation=1
Mode3\splitter\side1\side1\splitterSizes=@Invalid() Mode3\splitter\side1\side1\splitterSizes=@Invalid()
@ -289,21 +299,13 @@ Mode6\splitter\side1\side0\side1\gadget\activeConfiguration=raw
Mode6\splitter\side1\side1\type=uavGadget Mode6\splitter\side1\side1\type=uavGadget
Mode6\splitter\side1\side1\classId=ScopeGadget Mode6\splitter\side1\side1\classId=ScopeGadget
Mode6\splitter\side1\side1\gadget\activeConfiguration=Uptimes Mode6\splitter\side1\side1\gadget\activeConfiguration=Uptimes
Mode1\splitter\side0\side1\side0\gadget\activeConfiguration=Test Quad X
Mode2\splitter\side1\classId=UAVObjectBrowser
Mode2\splitter\side1\gadget\activeConfiguration=default
Mode3\splitter\side1\side0\gadget\activeConfiguration=Test Quad X
[KeyBindings] [KeyBindings]
size=0 size=0
[%General] [%General]
OverrideLanguage=en_AU
SaveSettingsOnExit=true SaveSettingsOnExit=true
TerminalEmulator=xterm -e
LastPreferenceCategory=LineardialGadget
LastPreferencePage=Roll Desired 1
SettingsWindowWidth=921
SettingsWindowHeight=534
[UAVGadgetConfigurations] [UAVGadgetConfigurations]
configInfo\version=1.2.0 configInfo\version=1.2.0
@ -1233,6 +1235,40 @@ LineardialGadget\Mainboard%20CPU\data\factor=1
LineardialGadget\Mainboard%20CPU\data\useOpenGLFlag=false LineardialGadget\Mainboard%20CPU\data\useOpenGLFlag=false
LineardialGadget\Mainboard%20CPU\configInfo\version=0.0.0 LineardialGadget\Mainboard%20CPU\configInfo\version=0.0.0
LineardialGadget\Mainboard%20CPU\configInfo\locked=false LineardialGadget\Mainboard%20CPU\configInfo\locked=false
LineardialGadget\Pitch\data\dFile=%%DATAPATH%%dials/default/lineardial-vertical.svg
LineardialGadget\Pitch\data\sourceDataObject=ManualControlCommand
LineardialGadget\Pitch\data\sourceObjectField=Pitch
LineardialGadget\Pitch\data\minValue=-1
LineardialGadget\Pitch\data\maxValue=1
LineardialGadget\Pitch\data\redMin=-1
LineardialGadget\Pitch\data\redMax=1
LineardialGadget\Pitch\data\yellowMin=-0.8
LineardialGadget\Pitch\data\yellowMax=0.8
LineardialGadget\Pitch\data\greenMin=-0.5
LineardialGadget\Pitch\data\greenMax=0.5
LineardialGadget\Pitch\data\font="Andale Mono,12,-1,5,75,0,0,0,0,0"
LineardialGadget\Pitch\data\decimalPlaces=2
LineardialGadget\Pitch\data\factor=1
LineardialGadget\Pitch\data\useOpenGLFlag=false
LineardialGadget\Pitch\configInfo\version=0.0.0
LineardialGadget\Pitch\configInfo\locked=false
LineardialGadget\Pitch%20Desired\data\dFile=%%DATAPATH%%dials/default/lineardial-vertical.svg
LineardialGadget\Pitch%20Desired\data\sourceDataObject=ActuatorDesired
LineardialGadget\Pitch%20Desired\data\sourceObjectField=Pitch
LineardialGadget\Pitch%20Desired\data\minValue=-1
LineardialGadget\Pitch%20Desired\data\maxValue=1
LineardialGadget\Pitch%20Desired\data\redMin=-1
LineardialGadget\Pitch%20Desired\data\redMax=1
LineardialGadget\Pitch%20Desired\data\yellowMin=-0.8
LineardialGadget\Pitch%20Desired\data\yellowMax=0.8
LineardialGadget\Pitch%20Desired\data\greenMin=-0.5
LineardialGadget\Pitch%20Desired\data\greenMax=0.5
LineardialGadget\Pitch%20Desired\data\font="Andale Mono,12,-1,5,75,0,0,0,0,0"
LineardialGadget\Pitch%20Desired\data\decimalPlaces=2
LineardialGadget\Pitch%20Desired\data\factor=1
LineardialGadget\Pitch%20Desired\data\useOpenGLFlag=false
LineardialGadget\Pitch%20Desired\configInfo\version=0.0.0
LineardialGadget\Pitch%20Desired\configInfo\locked=false
LineardialGadget\PitchActual\data\dFile=%%DATAPATH%%dials/default/lineardial-vertical.svg LineardialGadget\PitchActual\data\dFile=%%DATAPATH%%dials/default/lineardial-vertical.svg
LineardialGadget\PitchActual\data\sourceDataObject=AttitudeActual LineardialGadget\PitchActual\data\sourceDataObject=AttitudeActual
LineardialGadget\PitchActual\data\sourceObjectField=Pitch LineardialGadget\PitchActual\data\sourceObjectField=Pitch
@ -1267,6 +1303,23 @@ LineardialGadget\Roll\data\factor=1
LineardialGadget\Roll\data\useOpenGLFlag=false LineardialGadget\Roll\data\useOpenGLFlag=false
LineardialGadget\Roll\configInfo\version=0.0.0 LineardialGadget\Roll\configInfo\version=0.0.0
LineardialGadget\Roll\configInfo\locked=false LineardialGadget\Roll\configInfo\locked=false
LineardialGadget\Roll%20Desired\data\dFile=%%DATAPATH%%dials/default/lineardial-vertical.svg
LineardialGadget\Roll%20Desired\data\sourceDataObject=ActuatorDesired
LineardialGadget\Roll%20Desired\data\sourceObjectField=Roll
LineardialGadget\Roll%20Desired\data\minValue=-1
LineardialGadget\Roll%20Desired\data\maxValue=1
LineardialGadget\Roll%20Desired\data\redMin=-1
LineardialGadget\Roll%20Desired\data\redMax=1
LineardialGadget\Roll%20Desired\data\yellowMin=-0.8
LineardialGadget\Roll%20Desired\data\yellowMax=0.8
LineardialGadget\Roll%20Desired\data\greenMin=-0.5
LineardialGadget\Roll%20Desired\data\greenMax=0.5
LineardialGadget\Roll%20Desired\data\font="Andale Mono,12,-1,5,75,0,0,0,0,0"
LineardialGadget\Roll%20Desired\data\decimalPlaces=2
LineardialGadget\Roll%20Desired\data\factor=1
LineardialGadget\Roll%20Desired\data\useOpenGLFlag=false
LineardialGadget\Roll%20Desired\configInfo\version=0.0.0
LineardialGadget\Roll%20Desired\configInfo\locked=false
LineardialGadget\Telemetry%20RX%20Rate%20Horizontal\data\dFile=%%DATAPATH%%dials/default/lineardial-horizontal.svg LineardialGadget\Telemetry%20RX%20Rate%20Horizontal\data\dFile=%%DATAPATH%%dials/default/lineardial-horizontal.svg
LineardialGadget\Telemetry%20RX%20Rate%20Horizontal\data\sourceDataObject=GCSTelemetryStats LineardialGadget\Telemetry%20RX%20Rate%20Horizontal\data\sourceDataObject=GCSTelemetryStats
LineardialGadget\Telemetry%20RX%20Rate%20Horizontal\data\sourceObjectField=RxDataRate LineardialGadget\Telemetry%20RX%20Rate%20Horizontal\data\sourceObjectField=RxDataRate
@ -1335,6 +1388,23 @@ LineardialGadget\Yaw\data\factor=1
LineardialGadget\Yaw\data\useOpenGLFlag=false LineardialGadget\Yaw\data\useOpenGLFlag=false
LineardialGadget\Yaw\configInfo\version=0.0.0 LineardialGadget\Yaw\configInfo\version=0.0.0
LineardialGadget\Yaw\configInfo\locked=false LineardialGadget\Yaw\configInfo\locked=false
LineardialGadget\Yaw%20Desired\data\dFile=%%DATAPATH%%dials/default/lineardial-vertical.svg
LineardialGadget\Yaw%20Desired\data\sourceDataObject=ActuatorDesired
LineardialGadget\Yaw%20Desired\data\sourceObjectField=Yaw
LineardialGadget\Yaw%20Desired\data\minValue=-1
LineardialGadget\Yaw%20Desired\data\maxValue=1
LineardialGadget\Yaw%20Desired\data\redMin=-1
LineardialGadget\Yaw%20Desired\data\redMax=1
LineardialGadget\Yaw%20Desired\data\yellowMin=-0.8
LineardialGadget\Yaw%20Desired\data\yellowMax=0.8
LineardialGadget\Yaw%20Desired\data\greenMin=-0.5
LineardialGadget\Yaw%20Desired\data\greenMax=0.5
LineardialGadget\Yaw%20Desired\data\font="Andale Mono,12,-1,5,75,0,0,0,0,0"
LineardialGadget\Yaw%20Desired\data\decimalPlaces=2
LineardialGadget\Yaw%20Desired\data\factor=1
LineardialGadget\Yaw%20Desired\data\useOpenGLFlag=false
LineardialGadget\Yaw%20Desired\configInfo\version=0.0.0
LineardialGadget\Yaw%20Desired\configInfo\locked=false
ModelViewGadget\Aeroquad%20%2B\data\acFilename=%%DATAPATH%%models/multi/aeroquad/aeroquad_+.3ds ModelViewGadget\Aeroquad%20%2B\data\acFilename=%%DATAPATH%%models/multi/aeroquad/aeroquad_+.3ds
ModelViewGadget\Aeroquad%20%2B\data\bgFilename=%%DATAPATH%%models/backgrounds/default_background.png ModelViewGadget\Aeroquad%20%2B\data\bgFilename=%%DATAPATH%%models/backgrounds/default_background.png
ModelViewGadget\Aeroquad%20%2B\data\enableVbo=false ModelViewGadget\Aeroquad%20%2B\data\enableVbo=false
@ -1404,40 +1474,6 @@ OPMapGadget\Google%20Sat\data\showTileGridLines=false
OPMapGadget\Google%20Sat\data\accessMode=ServerAndCache OPMapGadget\Google%20Sat\data\accessMode=ServerAndCache
OPMapGadget\Google%20Sat\data\useMemoryCache=true OPMapGadget\Google%20Sat\data\useMemoryCache=true
OPMapGadget\Google%20Sat\data\uavSymbol=mapquad.png OPMapGadget\Google%20Sat\data\uavSymbol=mapquad.png
LineardialGadget\Pitch\data\dFile=%%DATAPATH%%dials/default/lineardial-vertical.svg
LineardialGadget\Pitch\data\sourceDataObject=ManualControlCommand
LineardialGadget\Pitch\data\sourceObjectField=Pitch
LineardialGadget\Pitch\data\minValue=-1
LineardialGadget\Pitch\data\maxValue=1
LineardialGadget\Pitch\data\redMin=-1
LineardialGadget\Pitch\data\redMax=1
LineardialGadget\Pitch\data\yellowMin=-0.8
LineardialGadget\Pitch\data\yellowMax=0.8
LineardialGadget\Pitch\data\greenMin=-0.5
LineardialGadget\Pitch\data\greenMax=0.5
LineardialGadget\Pitch\data\font="Andale Mono,12,-1,5,75,0,0,0,0,0"
LineardialGadget\Pitch\data\decimalPlaces=2
LineardialGadget\Pitch\data\factor=1
LineardialGadget\Pitch\data\useOpenGLFlag=false
LineardialGadget\Pitch\configInfo\version=0.0.0
LineardialGadget\Pitch\configInfo\locked=false
LineardialGadget\Pitch%20Desired\data\dFile=%%DATAPATH%%dials/default/lineardial-vertical.svg
LineardialGadget\Pitch%20Desired\data\sourceDataObject=ActuatorDesired
LineardialGadget\Pitch%20Desired\data\sourceObjectField=Pitch
LineardialGadget\Pitch%20Desired\data\minValue=-1
LineardialGadget\Pitch%20Desired\data\maxValue=1
LineardialGadget\Pitch%20Desired\data\redMin=-1
LineardialGadget\Pitch%20Desired\data\redMax=1
LineardialGadget\Pitch%20Desired\data\yellowMin=-0.8
LineardialGadget\Pitch%20Desired\data\yellowMax=0.8
LineardialGadget\Pitch%20Desired\data\greenMin=-0.5
LineardialGadget\Pitch%20Desired\data\greenMax=0.5
LineardialGadget\Pitch%20Desired\data\font="Andale Mono,12,-1,5,75,0,0,0,0,0"
LineardialGadget\Pitch%20Desired\data\decimalPlaces=2
LineardialGadget\Pitch%20Desired\data\factor=1
LineardialGadget\Pitch%20Desired\data\useOpenGLFlag=false
LineardialGadget\Pitch%20Desired\configInfo\version=0.0.0
LineardialGadget\Pitch%20Desired\configInfo\locked=false
OPMapGadget\Google%20Sat\data\cacheLocation=%%STOREPATH%%mapscache/ OPMapGadget\Google%20Sat\data\cacheLocation=%%STOREPATH%%mapscache/
OPMapGadget\Google%20Sat\configInfo\version=0.0.0 OPMapGadget\Google%20Sat\configInfo\version=0.0.0
OPMapGadget\Google%20Sat\configInfo\locked=false OPMapGadget\Google%20Sat\configInfo\locked=false
@ -1875,52 +1911,18 @@ Uploader\default\data\defaultStopBits=0
Uploader\default\data\defaultPort=/dev/ttyS0 Uploader\default\data\defaultPort=/dev/ttyS0
Uploader\default\configInfo\version=0.0.0 Uploader\default\configInfo\version=0.0.0
Uploader\default\configInfo\locked=false Uploader\default\configInfo\locked=false
LineardialGadget\Roll%20Desired\data\dFile=%%DATAPATH%%dials/default/lineardial-vertical.svg
LineardialGadget\Roll%20Desired\data\sourceDataObject=ActuatorDesired
LineardialGadget\Roll%20Desired\data\sourceObjectField=Roll
LineardialGadget\Roll%20Desired\data\minValue=-1
LineardialGadget\Roll%20Desired\data\maxValue=1
LineardialGadget\Roll%20Desired\data\redMin=-1
LineardialGadget\Roll%20Desired\data\redMax=1
LineardialGadget\Roll%20Desired\data\yellowMin=-0.8
LineardialGadget\Roll%20Desired\data\yellowMax=0.8
LineardialGadget\Roll%20Desired\data\greenMin=-0.5
LineardialGadget\Roll%20Desired\data\greenMax=0.5
LineardialGadget\Roll%20Desired\data\font="Andale Mono,12,-1,5,75,0,0,0,0,0"
LineardialGadget\Roll%20Desired\data\decimalPlaces=2
LineardialGadget\Roll%20Desired\data\factor=1
LineardialGadget\Roll%20Desired\data\useOpenGLFlag=false
LineardialGadget\Roll%20Desired\configInfo\version=0.0.0
LineardialGadget\Roll%20Desired\configInfo\locked=false
LineardialGadget\Yaw%20Desired\data\dFile=%%DATAPATH%%dials/default/lineardial-vertical.svg
LineardialGadget\Yaw%20Desired\data\sourceDataObject=ActuatorDesired
LineardialGadget\Yaw%20Desired\data\sourceObjectField=Yaw
LineardialGadget\Yaw%20Desired\data\minValue=-1
LineardialGadget\Yaw%20Desired\data\maxValue=1
LineardialGadget\Yaw%20Desired\data\redMin=-1
LineardialGadget\Yaw%20Desired\data\redMax=1
LineardialGadget\Yaw%20Desired\data\yellowMin=-0.8
LineardialGadget\Yaw%20Desired\data\yellowMax=0.8
LineardialGadget\Yaw%20Desired\data\greenMin=-0.5
LineardialGadget\Yaw%20Desired\data\greenMax=0.5
LineardialGadget\Yaw%20Desired\data\font="Andale Mono,12,-1,5,75,0,0,0,0,0"
LineardialGadget\Yaw%20Desired\data\decimalPlaces=2
LineardialGadget\Yaw%20Desired\data\factor=1
LineardialGadget\Yaw%20Desired\data\useOpenGLFlag=false
LineardialGadget\Yaw%20Desired\configInfo\version=0.0.0
LineardialGadget\Yaw%20Desired\configInfo\locked=false
[Plugins] [Plugins]
SoundNotifyPlugin\data\Current\1\SoundCollectionPath=%%DATAPATH%%sounds SoundNotifyPlugin\data\Current\1\SoundCollectionPath=
SoundNotifyPlugin\data\Current\1\CurrentLanguage=default SoundNotifyPlugin\data\Current\1\CurrentLanguage=
SoundNotifyPlugin\data\Current\1\ObjectField=Channel SoundNotifyPlugin\data\Current\1\ObjectField=
SoundNotifyPlugin\data\Current\1\DataObject=ActuatorCommand SoundNotifyPlugin\data\Current\1\DataObject=
SoundNotifyPlugin\data\Current\1\Value=Equal to SoundNotifyPlugin\data\Current\1\Value=
SoundNotifyPlugin\data\Current\1\ValueSpinBox=0 SoundNotifyPlugin\data\Current\1\ValueSpinBox=0
SoundNotifyPlugin\data\Current\1\Sound1= SoundNotifyPlugin\data\Current\1\Sound1=
SoundNotifyPlugin\data\Current\1\Sound2= SoundNotifyPlugin\data\Current\1\Sound2=
SoundNotifyPlugin\data\Current\1\Sound3= SoundNotifyPlugin\data\Current\1\Sound3=
SoundNotifyPlugin\data\Current\1\SayOrder=Never SoundNotifyPlugin\data\Current\1\SayOrder=
SoundNotifyPlugin\data\Current\1\Repeat= SoundNotifyPlugin\data\Current\1\Repeat=
SoundNotifyPlugin\data\Current\1\ExpireTimeout=0 SoundNotifyPlugin\data\Current\1\ExpireTimeout=0
SoundNotifyPlugin\data\Current\size=1 SoundNotifyPlugin\data\Current\size=1
@ -1928,9 +1930,3 @@ SoundNotifyPlugin\data\listNotifies\size=0
SoundNotifyPlugin\data\EnableSound=false SoundNotifyPlugin\data\EnableSound=false
SoundNotifyPlugin\configInfo\version=1.0.0 SoundNotifyPlugin\configInfo\version=1.0.0
SoundNotifyPlugin\configInfo\locked=false SoundNotifyPlugin\configInfo\locked=false
[IPconnection]
Current\1\HostName=
Current\1\Port=1
Current\1\UseTCP=0
Current\size=1

View File

@ -40,11 +40,13 @@ OPMapGadgetConfiguration::OPMapGadgetConfiguration(QString classId, QSettings*
m_accessMode("ServerAndCache"), m_accessMode("ServerAndCache"),
m_useMemoryCache(true), m_useMemoryCache(true),
m_cacheLocation(Utils::PathUtils().GetStoragePath() + "mapscache" + QDir::separator()), m_cacheLocation(Utils::PathUtils().GetStoragePath() + "mapscache" + QDir::separator()),
m_uavSymbol(QString::fromUtf8(":/uavs/images/mapquad.png")) m_uavSymbol(QString::fromUtf8(":/uavs/images/mapquad.png")),
m_maxUpdateRate(2000) // ms
{ {
//if a saved configuration exists load it //if a saved configuration exists load it
if(qSettings != 0) { if (qSettings != 0) {
QString mapProvider = qSettings->value("mapProvider").toString(); QString mapProvider = qSettings->value("mapProvider").toString();
int zoom = qSettings->value("defaultZoom").toInt(); int zoom = qSettings->value("defaultZoom").toInt();
double latitude= qSettings->value("defaultLatitude").toDouble(); double latitude= qSettings->value("defaultLatitude").toDouble();
@ -55,16 +57,25 @@ OPMapGadgetConfiguration::OPMapGadgetConfiguration(QString classId, QSettings*
bool useMemoryCache= qSettings->value("useMemoryCache").toBool(); bool useMemoryCache= qSettings->value("useMemoryCache").toBool();
QString cacheLocation= qSettings->value("cacheLocation").toString(); QString cacheLocation= qSettings->value("cacheLocation").toString();
QString uavSymbol=qSettings->value("uavSymbol").toString(); QString uavSymbol=qSettings->value("uavSymbol").toString();
int max_update_rate = qSettings->value("maxUpdateRate").toInt();
if (!mapProvider.isEmpty()) m_mapProvider = mapProvider; if (!mapProvider.isEmpty()) m_mapProvider = mapProvider;
m_defaultZoom = zoom; m_defaultZoom = zoom;
m_defaultLatitude = latitude; m_defaultLatitude = latitude;
m_defaultLongitude = longitude; m_defaultLongitude = longitude;
m_useOpenGL = useOpenGL; m_useOpenGL = useOpenGL;
m_showTileGridLines = showTileGridLines; m_showTileGridLines = showTileGridLines;
m_uavSymbol=uavSymbol; m_uavSymbol = uavSymbol;
if (!accessMode.isEmpty()) m_accessMode = accessMode;
m_maxUpdateRate = max_update_rate;
if (m_maxUpdateRate < 100 || m_maxUpdateRate > 5000)
m_maxUpdateRate = 2000;
if (!accessMode.isEmpty())
m_accessMode = accessMode;
m_useMemoryCache = useMemoryCache; m_useMemoryCache = useMemoryCache;
if (!cacheLocation.isEmpty()) m_cacheLocation = Utils::PathUtils().InsertStoragePath(cacheLocation); if (!cacheLocation.isEmpty())
m_cacheLocation = Utils::PathUtils().InsertStoragePath(cacheLocation);
} }
} }
@ -81,7 +92,9 @@ IUAVGadgetConfiguration * OPMapGadgetConfiguration::clone()
m->m_accessMode = m_accessMode; m->m_accessMode = m_accessMode;
m->m_useMemoryCache = m_useMemoryCache; m->m_useMemoryCache = m_useMemoryCache;
m->m_cacheLocation = m_cacheLocation; m->m_cacheLocation = m_cacheLocation;
m->m_uavSymbol=m_uavSymbol; m->m_uavSymbol = m_uavSymbol;
m->m_maxUpdateRate = m_maxUpdateRate;
return m; return m;
} }
@ -96,6 +109,7 @@ void OPMapGadgetConfiguration::saveConfig(QSettings* qSettings) const {
qSettings->setValue("useMemoryCache", m_useMemoryCache); qSettings->setValue("useMemoryCache", m_useMemoryCache);
qSettings->setValue("uavSymbol", m_uavSymbol); qSettings->setValue("uavSymbol", m_uavSymbol);
qSettings->setValue("cacheLocation", Utils::PathUtils().RemoveStoragePath(m_cacheLocation)); qSettings->setValue("cacheLocation", Utils::PathUtils().RemoveStoragePath(m_cacheLocation));
qSettings->setValue("maxUpdateRate", m_maxUpdateRate);
} }
void OPMapGadgetConfiguration::setCacheLocation(QString cacheLocation){ void OPMapGadgetConfiguration::setCacheLocation(QString cacheLocation){
m_cacheLocation = cacheLocation; m_cacheLocation = cacheLocation;

View File

@ -47,6 +47,7 @@ Q_PROPERTY(QString accessMode READ accessMode WRITE setAccessMode)
Q_PROPERTY(bool useMemoryCache READ useMemoryCache WRITE setUseMemoryCache) Q_PROPERTY(bool useMemoryCache READ useMemoryCache WRITE setUseMemoryCache)
Q_PROPERTY(QString cacheLocation READ cacheLocation WRITE setCacheLocation) Q_PROPERTY(QString cacheLocation READ cacheLocation WRITE setCacheLocation)
Q_PROPERTY(QString uavSymbol READ uavSymbol WRITE setUavSymbol) Q_PROPERTY(QString uavSymbol READ uavSymbol WRITE setUavSymbol)
Q_PROPERTY(int maxUpdateRate READ maxUpdateRate WRITE setMaxUpdateRate)
public: public:
explicit OPMapGadgetConfiguration(QString classId, QSettings* qSettings = 0, QObject *parent = 0); explicit OPMapGadgetConfiguration(QString classId, QSettings* qSettings = 0, QObject *parent = 0);
@ -64,6 +65,7 @@ public:
bool useMemoryCache() const { return m_useMemoryCache; } bool useMemoryCache() const { return m_useMemoryCache; }
QString cacheLocation() const { return m_cacheLocation; } QString cacheLocation() const { return m_cacheLocation; }
QString uavSymbol() const { return m_uavSymbol; } QString uavSymbol() const { return m_uavSymbol; }
int maxUpdateRate() const { return m_maxUpdateRate; }
public slots: public slots:
void setMapProvider(QString provider) { m_mapProvider = provider; } void setMapProvider(QString provider) { m_mapProvider = provider; }
@ -76,6 +78,8 @@ public slots:
void setUseMemoryCache(bool useMemoryCache) { m_useMemoryCache = useMemoryCache; } void setUseMemoryCache(bool useMemoryCache) { m_useMemoryCache = useMemoryCache; }
void setCacheLocation(QString cacheLocation); void setCacheLocation(QString cacheLocation);
void setUavSymbol(QString symbol){m_uavSymbol=symbol;} void setUavSymbol(QString symbol){m_uavSymbol=symbol;}
void setMaxUpdateRate(int update_rate){m_maxUpdateRate = update_rate;}
private: private:
QString m_mapProvider; QString m_mapProvider;
int m_defaultZoom; int m_defaultZoom;
@ -87,7 +91,7 @@ private:
bool m_useMemoryCache; bool m_useMemoryCache;
QString m_cacheLocation; QString m_cacheLocation;
QString m_uavSymbol; QString m_uavSymbol;
int m_maxUpdateRate;
}; };
#endif // OPMAP_GADGETCONFIGURATION_H #endif // OPMAP_GADGETCONFIGURATION_H

View File

@ -49,7 +49,9 @@ OPMapGadgetOptionsPage::OPMapGadgetOptionsPage(OPMapGadgetConfiguration *config,
QWidget *OPMapGadgetOptionsPage::createPage(QWidget *parent) QWidget *OPMapGadgetOptionsPage::createPage(QWidget *parent)
{ {
m_page = new Ui::OPMapGadgetOptionsPage(); int index;
m_page = new Ui::OPMapGadgetOptionsPage();
QWidget *w = new QWidget(parent); QWidget *w = new QWidget(parent);
m_page->setupUi(w); m_page->setupUi(w);
@ -61,9 +63,22 @@ QWidget *OPMapGadgetOptionsPage::createPage(QWidget *parent)
m_page->accessModeComboBox->clear(); m_page->accessModeComboBox->clear();
m_page->accessModeComboBox->addItems(mapcontrol::Helper::AccessModeTypes()); m_page->accessModeComboBox->addItems(mapcontrol::Helper::AccessModeTypes());
int index = m_page->providerComboBox->findText(m_config->mapProvider()); index = m_page->providerComboBox->findText(m_config->mapProvider());
index = (index >= 0) ? index : 0; index = (index >= 0) ? index : 0;
m_page->providerComboBox->setCurrentIndex(index); m_page->providerComboBox->setCurrentIndex(index);
// populate the map max update rate combobox
m_page->maxUpdateRateComboBox->clear();
m_page->maxUpdateRateComboBox->addItem("100ms", 100);
m_page->maxUpdateRateComboBox->addItem("200ms", 200);
m_page->maxUpdateRateComboBox->addItem("500ms", 500);
m_page->maxUpdateRateComboBox->addItem("1 sec", 1000);
m_page->maxUpdateRateComboBox->addItem("2 sec", 2000);
m_page->maxUpdateRateComboBox->addItem("5 sec", 5000);
index = m_page->maxUpdateRateComboBox->findData(m_config->maxUpdateRate());
index = (index >= 0) ? index : 4;
m_page->maxUpdateRateComboBox->setCurrentIndex(index);
m_page->zoomSpinBox->setValue(m_config->zoom()); m_page->zoomSpinBox->setValue(m_config->zoom());
m_page->latitudeSpinBox->setValue(m_config->latitude()); m_page->latitudeSpinBox->setValue(m_config->latitude());
@ -125,6 +140,7 @@ void OPMapGadgetOptionsPage::apply()
m_config->setUseMemoryCache(m_page->checkBoxUseMemoryCache->isChecked()); m_config->setUseMemoryCache(m_page->checkBoxUseMemoryCache->isChecked());
m_config->setCacheLocation(m_page->lineEditCacheLocation->path()); m_config->setCacheLocation(m_page->lineEditCacheLocation->path());
m_config->setUavSymbol(m_page->uavSymbolComboBox->itemData(m_page->uavSymbolComboBox->currentIndex()).toString()); m_config->setUavSymbol(m_page->uavSymbolComboBox->itemData(m_page->uavSymbolComboBox->currentIndex()).toString());
m_config->setMaxUpdateRate(m_page->maxUpdateRateComboBox->itemData(m_page->maxUpdateRateComboBox->currentIndex()).toInt());
} }
void OPMapGadgetOptionsPage::finish() void OPMapGadgetOptionsPage::finish()

View File

@ -30,7 +30,7 @@
<number>5</number> <number>5</number>
</property> </property>
<item row="1" column="0"> <item row="1" column="0">
<layout class="QGridLayout" name="gridLayout_3" rowstretch="0,0,0,0,0" rowminimumheight="22,22,22,0,22"> <layout class="QGridLayout" name="gridLayout_3" rowstretch="0,0,0,0,0,0" rowminimumheight="22,22,22,0,22,0">
<item row="2" column="0"> <item row="2" column="0">
<spacer name="horizontalSpacer_4"> <spacer name="horizontalSpacer_4">
<property name="orientation"> <property name="orientation">
@ -249,6 +249,19 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="3">
<widget class="QComboBox" name="maxUpdateRateComboBox"/>
</item>
<item row="5" column="2">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Default Max Update Rate </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item row="8" column="0"> <item row="8" column="0">

View File

@ -66,6 +66,8 @@ const int uav_trail_time_list[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
const int uav_trail_distance_list[] = {1, 2, 5, 10, 20, 50, 100, 200, 500}; // meters const int uav_trail_distance_list[] = {1, 2, 5, 10, 20, 50, 100, 200, 500}; // meters
const int max_update_rate_list[] = {100, 200, 500, 1000, 2000, 5000}; // milliseconds
// ************************************************************************************* // *************************************************************************************
@ -89,15 +91,17 @@ OPMapGadgetWidget::OPMapGadgetWidget(QWidget *parent) : QWidget(parent)
obm = NULL; obm = NULL;
obum = NULL; obum = NULL;
prev_tile_number = 0; m_prev_tile_number = 0;
min_zoom = max_zoom = 0; m_min_zoom = m_max_zoom = 0;
m_map_mode = Normal_MapMode; m_map_mode = Normal_MapMode;
telemetry_connected = false; m_maxUpdateRate = max_update_rate_list[4]; // 2 seconds
context_menu_lat_lon = mouse_lat_lon = internals::PointLatLng(0, 0); m_telemetry_connected = false;
m_context_menu_lat_lon = m_mouse_lat_lon = internals::PointLatLng(0, 0);
setMouseTracking(true); setMouseTracking(true);
@ -123,20 +127,20 @@ OPMapGadgetWidget::OPMapGadgetWidget(QWidget *parent) : QWidget(parent)
// ************** // **************
// default home position // default home position
home_position.coord = pos_lat_lon; m_home_position.coord = pos_lat_lon;
home_position.altitude = altitude; m_home_position.altitude = altitude;
home_position.locked = false; m_home_position.locked = false;
// ************** // **************
// default magic waypoint params // default magic waypoint params
magic_waypoint.map_wp_item = NULL; m_magic_waypoint.map_wp_item = NULL;
magic_waypoint.coord = home_position.coord; m_magic_waypoint.coord = m_home_position.coord;
magic_waypoint.altitude = altitude; m_magic_waypoint.altitude = altitude;
magic_waypoint.description = "Magic waypoint"; m_magic_waypoint.description = "Magic waypoint";
magic_waypoint.locked = false; m_magic_waypoint.locked = false;
magic_waypoint.time_seconds = 0; m_magic_waypoint.time_seconds = 0;
magic_waypoint.hold_time_seconds = 0; m_magic_waypoint.hold_time_seconds = 0;
// ************** // **************
// create the widget that holds the user controls and the map // create the widget that holds the user controls and the map
@ -157,8 +161,8 @@ OPMapGadgetWidget::OPMapGadgetWidget(QWidget *parent) : QWidget(parent)
m_widget->horizontalSliderZoom->setMinimum(m_map->MinZoom()); // m_widget->horizontalSliderZoom->setMinimum(m_map->MinZoom()); //
m_widget->horizontalSliderZoom->setMaximum(m_map->MaxZoom() + max_digital_zoom); // m_widget->horizontalSliderZoom->setMaximum(m_map->MaxZoom() + max_digital_zoom); //
min_zoom = m_widget->horizontalSliderZoom->minimum(); // minimum zoom we can accept m_min_zoom = m_widget->horizontalSliderZoom->minimum(); // minimum zoom we can accept
max_zoom = m_widget->horizontalSliderZoom->maximum(); // maximum zoom we can accept m_max_zoom = m_widget->horizontalSliderZoom->maximum(); // maximum zoom we can accept
m_map->SetMouseWheelZoomType(internals::MouseWheelZoomType::MousePositionWithoutCenter); // set how the mouse wheel zoom functions m_map->SetMouseWheelZoomType(internals::MouseWheelZoomType::MousePositionWithoutCenter); // set how the mouse wheel zoom functions
m_map->SetFollowMouse(true); // we want a contiuous mouse position reading m_map->SetFollowMouse(true); // we want a contiuous mouse position reading
@ -262,10 +266,10 @@ OPMapGadgetWidget::OPMapGadgetWidget(QWidget *parent) : QWidget(parent)
connect(m_map, SIGNAL(WPInserted(int const&, WayPointItem*)), this, SLOT(WPInserted(int const&, WayPointItem*))); connect(m_map, SIGNAL(WPInserted(int const&, WayPointItem*)), this, SLOT(WPInserted(int const&, WayPointItem*)));
connect(m_map, SIGNAL(WPDeleted(int const&)), this, SLOT(WPDeleted(int const&))); connect(m_map, SIGNAL(WPDeleted(int const&)), this, SLOT(WPDeleted(int const&)));
m_map->SetCurrentPosition(home_position.coord); // set the map position m_map->SetCurrentPosition(m_home_position.coord); // set the map position
m_map->Home->SetCoord(home_position.coord); // set the HOME position m_map->Home->SetCoord(m_home_position.coord); // set the HOME position
m_map->UAV->SetUAVPos(home_position.coord, 0.0); // set the UAV position m_map->UAV->SetUAVPos(m_home_position.coord, 0.0); // set the UAV position
m_map->GPS->SetUAVPos(home_position.coord, 0.0); // set the UAV position m_map->GPS->SetUAVPos(m_home_position.coord, 0.0); // set the UAV position
// ************** // **************
// create various context menu (mouse right click menu) actions // create various context menu (mouse right click menu) actions
@ -300,13 +304,14 @@ OPMapGadgetWidget::OPMapGadgetWidget(QWidget *parent) : QWidget(parent)
// create the desired timers // create the desired timers
m_updateTimer = new QTimer(); m_updateTimer = new QTimer();
m_updateTimer->setInterval(200); m_updateTimer->setInterval(m_maxUpdateRate);
connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updatePosition())); connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updatePosition()));
m_updateTimer->start(); m_updateTimer->start();
m_statusUpdateTimer = new QTimer(); m_statusUpdateTimer = new QTimer();
m_statusUpdateTimer->setInterval(100); m_statusUpdateTimer->setInterval(200);
connect(m_statusUpdateTimer, SIGNAL(timeout()), this, SLOT(updateMousePos())); // m_statusUpdateTimer->setInterval(m_maxUpdateRate);
connect(m_statusUpdateTimer, SIGNAL(timeout()), this, SLOT(updateMousePos()));
m_statusUpdateTimer->start(); m_statusUpdateTimer->start();
// ************** // **************
@ -385,22 +390,22 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
QString s; QString s;
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
if (event->reason() != QContextMenuEvent::Mouse) if (event->reason() != QContextMenuEvent::Mouse)
return; // not a mouse click event return; // not a mouse click event
// current mouse position // current mouse position
QPoint p = m_map->mapFromGlobal(event->globalPos()); QPoint p = m_map->mapFromGlobal(event->globalPos());
context_menu_lat_lon = m_map->GetFromLocalToLatLng(p); m_context_menu_lat_lon = m_map->GetFromLocalToLatLng(p);
// context_menu_lat_lon = m_map->currentMousePosition(); // m_context_menu_lat_lon = m_map->currentMousePosition();
if (!m_map->contentsRect().contains(p)) if (!m_map->contentsRect().contains(p))
return; // the mouse click was not on the map return; // the mouse click was not on the map
// show the mouse position // show the mouse position
s = QString::number(context_menu_lat_lon.Lat(), 'f', 7) + " " + QString::number(context_menu_lat_lon.Lng(), 'f', 7); s = QString::number(m_context_menu_lat_lon.Lat(), 'f', 7) + " " + QString::number(m_context_menu_lat_lon.Lng(), 'f', 7);
m_widget->labelMousePos->setText(s); m_widget->labelMousePos->setText(s);
// find out if we have a waypoint under the mouse cursor // find out if we have a waypoint under the mouse cursor
@ -425,6 +430,13 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
menu.addSeparator(); menu.addSeparator();
QMenu maxUpdateRateSubMenu(tr("&Max Update Rate ") + "(" + QString::number(m_maxUpdateRate) + " ms)", this);
for (int i = 0; i < maxUpdateRateAct.count(); i++)
maxUpdateRateSubMenu.addAction(maxUpdateRateAct.at(i));
menu.addMenu(&maxUpdateRateSubMenu);
menu.addSeparator();
switch (m_map_mode) switch (m_map_mode)
{ {
case Normal_MapMode: s = tr(" (Normal)"); break; case Normal_MapMode: s = tr(" (Normal)"); break;
@ -612,58 +624,81 @@ void OPMapGadgetWidget::keyPressEvent(QKeyEvent* event)
// ************************************************************************************* // *************************************************************************************
// timer signals // timer signals
/** /**
Updates the UAV position on the map. It is called every 200ms Updates the UAV position on the map. It is called every 200ms
by a timer. by a timer.
TODO: consider updating upon object update, not timer. TODO: consider updating upon object update, not timer.
from Pip: No don't update on object update - had reports that peoples PC's can't cope with high update rates - have had to allow user to set map update from 100ms to 5 seconds (depending on their PC's graphics processing ability), so this needs to be kept on a timer.
*/ */
void OPMapGadgetWidget::updatePosition() void OPMapGadgetWidget::updatePosition()
{ {
if (!m_widget || !m_map) double uav_latitude, uav_longitude, uav_altitude, uav_yaw;
return; double gps_latitude, gps_longitude, gps_altitude, gps_heading;
internals::PointLatLng uav_pos;
internals::PointLatLng gps_pos;
if (!m_widget || !m_map)
return;
QMutexLocker locker(&m_map_mutex); QMutexLocker locker(&m_map_mutex);
//Pip I'm sorry, I know this was here with a purpose vvv // Pip I'm sorry, I know this was here with a purpose vvv
//if (!telemetry_connected) // from Pip: let you off :)
// return; //if (!telemetry_connected)
// return;
double latitude; // *************
double longitude; // get the current UAV details
double altitude;
// get current UAV position // get current UAV position
if (!getUAVPosition(latitude, longitude, altitude)) if (!getUAVPosition(uav_latitude, uav_longitude, uav_altitude))
return; return;
// get current UAV heading // get current UAV heading
float yaw = getUAV_Yaw(); uav_yaw = getUAV_Yaw();
internals::PointLatLng uav_pos = internals::PointLatLng(latitude, longitude); // current UAV position uav_pos = internals::PointLatLng(uav_latitude, uav_longitude);
float uav_heading_degrees = yaw; // current UAV heading
float uav_altitude_meters = altitude; // current UAV height // *************
float uav_ground_speed_meters_per_second = 0; //data.Groundspeed; // current UAV ground speed // get the current GPS details
// get current GPS position
if (!getGPSPosition(gps_latitude, gps_longitude, gps_altitude))
return;
// get current GPS heading
// gps_heading = getGPS_Heading();
gps_heading = 0;
gps_pos = internals::PointLatLng(gps_latitude, gps_longitude);
// *************
// display the UAV position
// display the UAV lat/lon position
QString str = QString str =
"lat: " + QString::number(uav_pos.Lat(), 'f', 7) + "lat: " + QString::number(uav_pos.Lat(), 'f', 7) +
" lon: " + QString::number(uav_pos.Lng(), 'f', 7) + " lon: " + QString::number(uav_pos.Lng(), 'f', 7) +
" " + QString::number(uav_heading_degrees, 'f', 1) + "deg" + " " + QString::number(uav_yaw, 'f', 1) + "deg" +
" " + QString::number(uav_altitude_meters, 'f', 1) + "m" + " " + QString::number(uav_altitude, 'f', 1) + "m";
" " + QString::number(uav_ground_speed_meters_per_second, 'f', 1) + "m/s"; // " " + QString::number(uav_ground_speed_meters_per_second, 'f', 1) + "m/s";
m_widget->labelUAVPos->setText(str); m_widget->labelUAVPos->setText(str);
m_map->UAV->SetUAVPos(uav_pos, uav_altitude_meters); // set the maps UAV position // *************
// qDebug()<<"UAVPOSITION"<<uav_pos.ToString(); // set the UAV icon position on the map
m_map->UAV->SetUAVHeading(uav_heading_degrees); // set the maps UAV heading
if (!getGPSPosition(latitude, longitude, altitude)) m_map->UAV->SetUAVPos(uav_pos, uav_altitude); // set the maps UAV position
return; // qDebug()<<"UAVPOSITION"<<uav_pos.ToString();
m_map->UAV->SetUAVHeading(uav_yaw); // set the maps UAV heading
uav_pos = internals::PointLatLng(latitude, longitude); // current UAV position // *************
m_map->GPS->SetUAVPos(uav_pos, uav_altitude_meters); // set the maps UAV position // set the GPS icon position on the map
m_map->GPS->SetUAVHeading(uav_heading_degrees); // set the maps UAV heading
m_map->GPS->SetUAVPos(gps_pos, gps_altitude); // set the maps GPS position
m_map->GPS->SetUAVHeading(gps_heading); // set the maps GPS heading
// *************
} }
/** /**
@ -672,8 +707,8 @@ void OPMapGadgetWidget::updatePosition()
*/ */
void OPMapGadgetWidget::updateMousePos() void OPMapGadgetWidget::updateMousePos()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
QMutexLocker locker(&m_map_mutex); QMutexLocker locker(&m_map_mutex);
@ -696,14 +731,14 @@ void OPMapGadgetWidget::updateMousePos()
// find out if we have a waypoint under the mouse cursor // find out if we have a waypoint under the mouse cursor
mapcontrol::WayPointItem *wp = qgraphicsitem_cast<mapcontrol::WayPointItem *>(item); mapcontrol::WayPointItem *wp = qgraphicsitem_cast<mapcontrol::WayPointItem *>(item);
if (mouse_lat_lon == lat_lon) if (m_mouse_lat_lon == lat_lon)
return; // the mouse has not moved return; // the mouse has not moved
mouse_lat_lon = lat_lon; // yes it has! m_mouse_lat_lon = lat_lon; // yes it has!
internals::PointLatLng home_lat_lon = m_map->Home->Coord(); internals::PointLatLng home_lat_lon = m_map->Home->Coord();
QString s = QString::number(mouse_lat_lon.Lat(), 'f', 7) + " " + QString::number(mouse_lat_lon.Lng(), 'f', 7); QString s = QString::number(m_mouse_lat_lon.Lat(), 'f', 7) + " " + QString::number(m_mouse_lat_lon.Lng(), 'f', 7);
if (wp) if (wp)
{ {
s += " wp[" + QString::number(wp->Number()) + "]"; s += " wp[" + QString::number(wp->Number()) + "]";
@ -718,8 +753,8 @@ void OPMapGadgetWidget::updateMousePos()
{ {
s += " home"; s += " home";
double dist = distance(home_lat_lon, mouse_lat_lon); double dist = distance(home_lat_lon, m_mouse_lat_lon);
double bear = bearing(home_lat_lon, mouse_lat_lon); double bear = bearing(home_lat_lon, m_mouse_lat_lon);
s += " " + QString::number(dist * 1000, 'f', 1) + "m"; s += " " + QString::number(dist * 1000, 'f', 1) + "m";
s += " " + QString::number(bear, 'f', 1) + "deg"; s += " " + QString::number(bear, 'f', 1) + "deg";
} }
@ -753,22 +788,22 @@ void OPMapGadgetWidget::updateMousePos()
*/ */
void OPMapGadgetWidget::zoomChanged(double zoomt, double zoom, double zoomd) void OPMapGadgetWidget::zoomChanged(double zoomt, double zoom, double zoomd)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
QString s = "tot:" + QString::number(zoomt, 'f', 1) + " rea:" + QString::number(zoom, 'f', 1) + " dig:" + QString::number(zoomd, 'f', 1); QString s = "tot:" + QString::number(zoomt, 'f', 1) + " rea:" + QString::number(zoom, 'f', 1) + " dig:" + QString::number(zoomd, 'f', 1);
m_widget->labelMapZoom->setText(s); m_widget->labelMapZoom->setText(s);
int i_zoom = (int)(zoomt + 0.5); int i_zoom = (int)(zoomt + 0.5);
if (i_zoom < min_zoom) i_zoom = min_zoom; if (i_zoom < m_min_zoom) i_zoom = m_min_zoom;
else else
if (i_zoom > max_zoom) i_zoom = max_zoom; if (i_zoom > m_max_zoom) i_zoom = m_max_zoom;
if (m_widget->horizontalSliderZoom->value() != i_zoom) if (m_widget->horizontalSliderZoom->value() != i_zoom)
m_widget->horizontalSliderZoom->setValue(i_zoom); // set the GUI zoom slider position m_widget->horizontalSliderZoom->setValue(i_zoom); // set the GUI zoom slider position
int index0_zoom = i_zoom - min_zoom; // zoom level starting at index level '0' int index0_zoom = i_zoom - m_min_zoom; // zoom level starting at index level '0'
if (index0_zoom < zoomAct.count()) if (index0_zoom < zoomAct.count())
zoomAct.at(index0_zoom)->setChecked(true); // set the right-click context menu zoom level zoomAct.at(index0_zoom)->setChecked(true); // set the right-click context menu zoom level
} }
@ -779,8 +814,8 @@ void OPMapGadgetWidget::OnMapDrag()
void OPMapGadgetWidget::OnCurrentPositionChanged(internals::PointLatLng point) void OPMapGadgetWidget::OnCurrentPositionChanged(internals::PointLatLng point)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
QString coord_str = QString::number(point.Lat(), 'f', 7) + " " + QString::number(point.Lng(), 'f', 7) + " "; QString coord_str = QString::number(point.Lat(), 'f', 7) + " " + QString::number(point.Lng(), 'f', 7) + " ";
m_widget->labelMapPos->setText(coord_str); m_widget->labelMapPos->setText(coord_str);
@ -791,8 +826,8 @@ void OPMapGadgetWidget::OnCurrentPositionChanged(internals::PointLatLng point)
*/ */
void OPMapGadgetWidget::OnTilesStillToLoad(int number) void OPMapGadgetWidget::OnTilesStillToLoad(int number)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
// if (prev_tile_number < number || m_widget->progressBarMap->maximum() < number) // if (prev_tile_number < number || m_widget->progressBarMap->maximum() < number)
// m_widget->progressBarMap->setMaximum(number); // m_widget->progressBarMap->setMaximum(number);
@ -804,7 +839,7 @@ void OPMapGadgetWidget::OnTilesStillToLoad(int number)
// m_widget->labelNumTilesToLoad->setText(QString::number(number)); // m_widget->labelNumTilesToLoad->setText(QString::number(number));
prev_tile_number = number; m_prev_tile_number = number;
} }
/** /**
@ -812,8 +847,8 @@ void OPMapGadgetWidget::OnTilesStillToLoad(int number)
*/ */
void OPMapGadgetWidget::OnTileLoadStart() void OPMapGadgetWidget::OnTileLoadStart()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_widget->progressBarMap->setVisible(true); m_widget->progressBarMap->setVisible(true);
} }
@ -826,8 +861,8 @@ void OPMapGadgetWidget::OnTileLoadStart()
void OPMapGadgetWidget::OnTileLoadComplete() void OPMapGadgetWidget::OnTileLoadComplete()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_widget->progressBarMap->setVisible(false); m_widget->progressBarMap->setVisible(false);
} }
@ -878,11 +913,11 @@ void OPMapGadgetWidget::WPValuesChanged(WayPointItem *waypoint)
case MagicWaypoint_MapMode: case MagicWaypoint_MapMode:
// update our copy of the magic waypoint // update our copy of the magic waypoint
if (magic_waypoint.map_wp_item && magic_waypoint.map_wp_item == waypoint) if (m_magic_waypoint.map_wp_item && m_magic_waypoint.map_wp_item == waypoint)
{ {
magic_waypoint.coord = waypoint->Coord(); m_magic_waypoint.coord = waypoint->Coord();
magic_waypoint.altitude = waypoint->Altitude(); m_magic_waypoint.altitude = waypoint->Altitude();
magic_waypoint.description = waypoint->Description(); m_magic_waypoint.description = waypoint->Description();
// move the UAV to the magic waypoint position // move the UAV to the magic waypoint position
// moveToMagicWaypointPosition(); // moveToMagicWaypointPosition();
@ -930,8 +965,8 @@ void OPMapGadgetWidget::on_toolButtonMapHome_clicked()
void OPMapGadgetWidget::on_toolButtonMapUAV_clicked() void OPMapGadgetWidget::on_toolButtonMapUAV_clicked()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
QMutexLocker locker(&m_map_mutex); QMutexLocker locker(&m_map_mutex);
@ -940,16 +975,16 @@ void OPMapGadgetWidget::on_toolButtonMapUAV_clicked()
void OPMapGadgetWidget::on_toolButtonMapUAVheading_clicked() void OPMapGadgetWidget::on_toolButtonMapUAVheading_clicked()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
followUAVheadingAct->toggle(); followUAVheadingAct->toggle();
} }
void OPMapGadgetWidget::on_horizontalSliderZoom_sliderMoved(int position) void OPMapGadgetWidget::on_horizontalSliderZoom_sliderMoved(int position)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
QMutexLocker locker(&m_map_mutex); QMutexLocker locker(&m_map_mutex);
@ -982,7 +1017,7 @@ void OPMapGadgetWidget::on_toolButtonMoveToWP_clicked()
void OPMapGadgetWidget::onTelemetryConnect() void OPMapGadgetWidget::onTelemetryConnect()
{ {
telemetry_connected = true; m_telemetry_connected = true;
if (!obum) return; if (!obum) return;
@ -998,14 +1033,14 @@ void OPMapGadgetWidget::onTelemetryConnect()
setHome(internals::PointLatLng(LLA[0], LLA[1])); setHome(internals::PointLatLng(LLA[0], LLA[1]));
if (m_map) if (m_map)
m_map->SetCurrentPosition(home_position.coord); // set the map position m_map->SetCurrentPosition(m_home_position.coord); // set the map position
// *********************** // ***********************
} }
void OPMapGadgetWidget::onTelemetryDisconnect() void OPMapGadgetWidget::onTelemetryDisconnect()
{ {
telemetry_connected = false; m_telemetry_connected = false;
} }
// Updates the Home position icon whenever the HomePosition object is updated // Updates the Home position icon whenever the HomePosition object is updated
@ -1027,8 +1062,8 @@ void OPMapGadgetWidget::homePositionUpdated(UAVObject *hp)
*/ */
void OPMapGadgetWidget::setHome(QPointF pos) void OPMapGadgetWidget::setHome(QPointF pos)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
double latitude = pos.x(); double latitude = pos.x();
double longitude = pos.y(); double longitude = pos.y();
@ -1051,8 +1086,8 @@ void OPMapGadgetWidget::setHome(QPointF pos)
*/ */
void OPMapGadgetWidget::setHome(internals::PointLatLng pos_lat_lon) void OPMapGadgetWidget::setHome(internals::PointLatLng pos_lat_lon)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
if (pos_lat_lon.Lat() != pos_lat_lon.Lat() || pos_lat_lon.Lng() != pos_lat_lon.Lng()) if (pos_lat_lon.Lat() != pos_lat_lon.Lat() || pos_lat_lon.Lng() != pos_lat_lon.Lng())
return;; // nan prevention return;; // nan prevention
@ -1074,9 +1109,9 @@ void OPMapGadgetWidget::setHome(internals::PointLatLng pos_lat_lon)
// ********* // *********
home_position.coord = internals::PointLatLng(latitude, longitude); m_home_position.coord = internals::PointLatLng(latitude, longitude);
m_map->Home->SetCoord(home_position.coord); m_map->Home->SetCoord(m_home_position.coord);
m_map->Home->RefreshPos(); m_map->Home->RefreshPos();
// move the magic waypoint to keep it within the safe area boundry // move the magic waypoint to keep it within the safe area boundry
@ -1089,52 +1124,74 @@ void OPMapGadgetWidget::setHome(internals::PointLatLng pos_lat_lon)
*/ */
void OPMapGadgetWidget::goHome() void OPMapGadgetWidget::goHome()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
followUAVpositionAct->setChecked(false); followUAVpositionAct->setChecked(false);
internals::PointLatLng home_pos = home_position.coord; // get the home location internals::PointLatLng home_pos = m_home_position.coord; // get the home location
m_map->SetCurrentPosition(home_pos); // center the map onto the home location m_map->SetCurrentPosition(home_pos); // center the map onto the home location
} }
void OPMapGadgetWidget::zoomIn() void OPMapGadgetWidget::zoomIn()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
int zoom = m_map->ZoomTotal() + 1; int zoom = m_map->ZoomTotal() + 1;
if (zoom < min_zoom) zoom = min_zoom; if (zoom < m_min_zoom) zoom = m_min_zoom;
else else
if (zoom > max_zoom) zoom = max_zoom; if (zoom > m_max_zoom) zoom = m_max_zoom;
m_map->SetZoom(zoom); m_map->SetZoom(zoom);
} }
void OPMapGadgetWidget::zoomOut() void OPMapGadgetWidget::zoomOut()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
int zoom = m_map->ZoomTotal() - 1; int zoom = m_map->ZoomTotal() - 1;
if (zoom < min_zoom) zoom = min_zoom; if (zoom < m_min_zoom) zoom = m_min_zoom;
else else
if (zoom > max_zoom) zoom = max_zoom; if (zoom > m_max_zoom) zoom = m_max_zoom;
m_map->SetZoom(zoom); m_map->SetZoom(zoom);
} }
void OPMapGadgetWidget::setMaxUpdateRate(int update_rate)
{
if (!m_widget || !m_map)
return;
int list_size = sizeof(max_update_rate_list) / sizeof(max_update_rate_list[0]);
int min_rate = max_update_rate_list[0];
int max_rate = max_update_rate_list[list_size - 1];
if (update_rate < min_rate) update_rate = min_rate;
else
if (update_rate > max_rate) update_rate = max_rate;
m_maxUpdateRate = update_rate;
if (m_updateTimer)
m_updateTimer->setInterval(m_maxUpdateRate);
// if (m_statusUpdateTimer)
// m_statusUpdateTimer->setInterval(m_maxUpdateRate);
}
void OPMapGadgetWidget::setZoom(int zoom) void OPMapGadgetWidget::setZoom(int zoom)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
if (zoom < min_zoom) zoom = min_zoom; if (zoom < m_min_zoom) zoom = m_min_zoom;
else else
if (zoom > max_zoom) zoom = max_zoom; if (zoom > m_max_zoom) zoom = m_max_zoom;
internals::MouseWheelZoomType::Types zoom_type = m_map->GetMouseWheelZoomType(); internals::MouseWheelZoomType::Types zoom_type = m_map->GetMouseWheelZoomType();
m_map->SetMouseWheelZoomType(internals::MouseWheelZoomType::ViewCenter); m_map->SetMouseWheelZoomType(internals::MouseWheelZoomType::ViewCenter);
@ -1146,8 +1203,8 @@ void OPMapGadgetWidget::setZoom(int zoom)
void OPMapGadgetWidget::setPosition(QPointF pos) void OPMapGadgetWidget::setPosition(QPointF pos)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
double latitude = pos.y(); double latitude = pos.y();
double longitude = pos.x(); double longitude = pos.x();
@ -1168,48 +1225,48 @@ void OPMapGadgetWidget::setPosition(QPointF pos)
void OPMapGadgetWidget::setMapProvider(QString provider) void OPMapGadgetWidget::setMapProvider(QString provider)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->SetMapType(mapcontrol::Helper::MapTypeFromString(provider)); m_map->SetMapType(mapcontrol::Helper::MapTypeFromString(provider));
} }
void OPMapGadgetWidget::setAccessMode(QString accessMode) void OPMapGadgetWidget::setAccessMode(QString accessMode)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->configuration->SetAccessMode(mapcontrol::Helper::AccessModeFromString(accessMode)); m_map->configuration->SetAccessMode(mapcontrol::Helper::AccessModeFromString(accessMode));
} }
void OPMapGadgetWidget::setUseOpenGL(bool useOpenGL) void OPMapGadgetWidget::setUseOpenGL(bool useOpenGL)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->SetUseOpenGL(useOpenGL); m_map->SetUseOpenGL(useOpenGL);
} }
void OPMapGadgetWidget::setShowTileGridLines(bool showTileGridLines) void OPMapGadgetWidget::setShowTileGridLines(bool showTileGridLines)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->SetShowTileGridLines(showTileGridLines); m_map->SetShowTileGridLines(showTileGridLines);
} }
void OPMapGadgetWidget::setUseMemoryCache(bool useMemoryCache) void OPMapGadgetWidget::setUseMemoryCache(bool useMemoryCache)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->configuration->SetUseMemoryCache(useMemoryCache); m_map->configuration->SetUseMemoryCache(useMemoryCache);
} }
void OPMapGadgetWidget::setCacheLocation(QString cacheLocation) void OPMapGadgetWidget::setCacheLocation(QString cacheLocation)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
cacheLocation = cacheLocation.simplified(); // remove any surrounding spaces cacheLocation = cacheLocation.simplified(); // remove any surrounding spaces
@ -1235,8 +1292,8 @@ void OPMapGadgetWidget::setCacheLocation(QString cacheLocation)
void OPMapGadgetWidget::setMapMode(opMapModeType mode) void OPMapGadgetWidget::setMapMode(opMapModeType mode)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
if (mode != Normal_MapMode && mode != MagicWaypoint_MapMode) if (mode != Normal_MapMode && mode != MagicWaypoint_MapMode)
mode = Normal_MapMode; // fix error mode = Normal_MapMode; // fix error
@ -1268,12 +1325,12 @@ void OPMapGadgetWidget::setMapMode(opMapModeType mode)
hideMagicWaypointControls(); hideMagicWaypointControls();
// delete the magic waypoint from the map // delete the magic waypoint from the map
if (magic_waypoint.map_wp_item) if (m_magic_waypoint.map_wp_item)
{ {
magic_waypoint.coord = magic_waypoint.map_wp_item->Coord(); m_magic_waypoint.coord = m_magic_waypoint.map_wp_item->Coord();
magic_waypoint.altitude = magic_waypoint.map_wp_item->Altitude(); m_magic_waypoint.altitude = m_magic_waypoint.map_wp_item->Altitude();
magic_waypoint.description = magic_waypoint.map_wp_item->Description(); m_magic_waypoint.description = m_magic_waypoint.map_wp_item->Description();
magic_waypoint.map_wp_item = NULL; m_magic_waypoint.map_wp_item = NULL;
} }
m_map->WPDeleteAll(); m_map->WPDeleteAll();
@ -1320,10 +1377,10 @@ void OPMapGadgetWidget::setMapMode(opMapModeType mode)
m_waypoint_list_mutex.unlock(); m_waypoint_list_mutex.unlock();
// restore the magic waypoint on the map // restore the magic waypoint on the map
magic_waypoint.map_wp_item = m_map->WPCreate(magic_waypoint.coord, magic_waypoint.altitude, magic_waypoint.description); m_magic_waypoint.map_wp_item = m_map->WPCreate(m_magic_waypoint.coord, m_magic_waypoint.altitude, m_magic_waypoint.description);
magic_waypoint.map_wp_item->setZValue(10 + magic_waypoint.map_wp_item->Number()); m_magic_waypoint.map_wp_item->setZValue(10 + m_magic_waypoint.map_wp_item->Number());
magic_waypoint.map_wp_item->SetShowNumber(false); m_magic_waypoint.map_wp_item->SetShowNumber(false);
magic_waypoint.map_wp_item->picture.load(QString::fromUtf8(":/opmap/images/waypoint_marker3.png")); m_magic_waypoint.map_wp_item->picture.load(QString::fromUtf8(":/opmap/images/waypoint_marker3.png"));
break; break;
} }
@ -1334,8 +1391,10 @@ void OPMapGadgetWidget::setMapMode(opMapModeType mode)
void OPMapGadgetWidget::createActions() void OPMapGadgetWidget::createActions()
{ {
if (!m_widget) int list_size;
return;
if (!m_widget || !m_map)
return;
// *********************** // ***********************
// create menu actions // create menu actions
@ -1503,7 +1562,7 @@ void OPMapGadgetWidget::createActions()
zoomActGroup = new QActionGroup(this); zoomActGroup = new QActionGroup(this);
connect(zoomActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onZoomActGroup_triggered(QAction *))); connect(zoomActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onZoomActGroup_triggered(QAction *)));
zoomAct.clear(); zoomAct.clear();
for (int i = min_zoom; i <= max_zoom; i++) for (int i = m_min_zoom; i <= m_max_zoom; i++)
{ {
QAction *zoom_act = new QAction(QString::number(i), zoomActGroup); QAction *zoom_act = new QAction(QString::number(i), zoomActGroup);
zoom_act->setCheckable(true); zoom_act->setCheckable(true);
@ -1511,7 +1570,22 @@ void OPMapGadgetWidget::createActions()
zoomAct.append(zoom_act); zoomAct.append(zoom_act);
} }
// ***** maxUpdateRateActGroup = new QActionGroup(this);
connect(maxUpdateRateActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onMaxUpdateRateActGroup_triggered(QAction *)));
maxUpdateRateAct.clear();
list_size = sizeof(max_update_rate_list) / sizeof(max_update_rate_list[0]);
for (int i = 0; i < list_size; i++)
{
QAction *maxUpdateRate_act;
int j = max_update_rate_list[i];
maxUpdateRate_act = new QAction(QString::number(j), maxUpdateRateActGroup);
maxUpdateRate_act->setCheckable(true);
maxUpdateRate_act->setData(j);
maxUpdateRate_act->setChecked(j == m_maxUpdateRate);
maxUpdateRateAct.append(maxUpdateRate_act);
}
// *****
// safe area // safe area
showSafeAreaAct = new QAction(tr("Show Safe Area"), this); showSafeAreaAct = new QAction(tr("Show Safe Area"), this);
@ -1523,7 +1597,8 @@ void OPMapGadgetWidget::createActions()
safeAreaActGroup = new QActionGroup(this); safeAreaActGroup = new QActionGroup(this);
connect(safeAreaActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onSafeAreaActGroup_triggered(QAction *))); connect(safeAreaActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onSafeAreaActGroup_triggered(QAction *)));
safeAreaAct.clear(); safeAreaAct.clear();
for (int i = 0; i < (int)(sizeof(safe_area_radius_list) / sizeof(safe_area_radius_list[0])); i++) list_size = sizeof(safe_area_radius_list) / sizeof(safe_area_radius_list[0]);
for (int i = 0; i < list_size; i++)
{ {
int safeArea = safe_area_radius_list[i]; int safeArea = safe_area_radius_list[i];
QAction *safeArea_act = new QAction(QString::number(safeArea) + "m", safeAreaActGroup); QAction *safeArea_act = new QAction(QString::number(safeArea) + "m", safeAreaActGroup);
@ -1569,7 +1644,8 @@ void OPMapGadgetWidget::createActions()
uavTrailTimeActGroup = new QActionGroup(this); uavTrailTimeActGroup = new QActionGroup(this);
connect(uavTrailTimeActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onUAVTrailTimeActGroup_triggered(QAction *))); connect(uavTrailTimeActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onUAVTrailTimeActGroup_triggered(QAction *)));
uavTrailTimeAct.clear(); uavTrailTimeAct.clear();
for (int i = 0; i < (int)(sizeof(uav_trail_time_list) / sizeof(uav_trail_time_list[0])); i++) list_size = sizeof(uav_trail_time_list) / sizeof(uav_trail_time_list[0]);
for (int i = 0; i < list_size; i++)
{ {
int uav_trail_time = uav_trail_time_list[i]; int uav_trail_time = uav_trail_time_list[i];
QAction *uavTrailTime_act = new QAction(QString::number(uav_trail_time) + " sec", uavTrailTimeActGroup); QAction *uavTrailTime_act = new QAction(QString::number(uav_trail_time) + " sec", uavTrailTimeActGroup);
@ -1582,7 +1658,8 @@ void OPMapGadgetWidget::createActions()
uavTrailDistanceActGroup = new QActionGroup(this); uavTrailDistanceActGroup = new QActionGroup(this);
connect(uavTrailDistanceActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onUAVTrailDistanceActGroup_triggered(QAction *))); connect(uavTrailDistanceActGroup, SIGNAL(triggered(QAction *)), this, SLOT(onUAVTrailDistanceActGroup_triggered(QAction *)));
uavTrailDistanceAct.clear(); uavTrailDistanceAct.clear();
for (int i = 0; i < (int)(sizeof(uav_trail_distance_list) / sizeof(uav_trail_distance_list[0])); i++) list_size = sizeof(uav_trail_distance_list) / sizeof(uav_trail_distance_list[0]);
for (int i = 0; i < list_size; i++)
{ {
int uav_trail_distance = uav_trail_distance_list[i]; int uav_trail_distance = uav_trail_distance_list[i];
QAction *uavTrailDistance_act = new QAction(QString::number(uav_trail_distance) + " meters", uavTrailDistanceActGroup); QAction *uavTrailDistance_act = new QAction(QString::number(uav_trail_distance) + " meters", uavTrailDistanceActGroup);
@ -1599,62 +1676,59 @@ void OPMapGadgetWidget::createActions()
void OPMapGadgetWidget::onReloadAct_triggered() void OPMapGadgetWidget::onReloadAct_triggered()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->ReloadMap(); m_map->ReloadMap();
} }
void OPMapGadgetWidget::onCopyMouseLatLonToClipAct_triggered() void OPMapGadgetWidget::onCopyMouseLatLonToClipAct_triggered()
{ {
// QClipboard *clipboard = qApp->clipboard();
QClipboard *clipboard = QApplication::clipboard(); QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(QString::number(context_menu_lat_lon.Lat(), 'f', 7) + ", " + QString::number(context_menu_lat_lon.Lng(), 'f', 7), QClipboard::Clipboard); clipboard->setText(QString::number(m_context_menu_lat_lon.Lat(), 'f', 7) + ", " + QString::number(m_context_menu_lat_lon.Lng(), 'f', 7), QClipboard::Clipboard);
} }
void OPMapGadgetWidget::onCopyMouseLatToClipAct_triggered() void OPMapGadgetWidget::onCopyMouseLatToClipAct_triggered()
{ {
// QClipboard *clipboard = qApp->clipboard();
QClipboard *clipboard = QApplication::clipboard(); QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(QString::number(context_menu_lat_lon.Lat(), 'f', 7), QClipboard::Clipboard); clipboard->setText(QString::number(m_context_menu_lat_lon.Lat(), 'f', 7), QClipboard::Clipboard);
} }
void OPMapGadgetWidget::onCopyMouseLonToClipAct_triggered() void OPMapGadgetWidget::onCopyMouseLonToClipAct_triggered()
{ {
// QClipboard *clipboard = qApp->clipboard();
QClipboard *clipboard = QApplication::clipboard(); QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(QString::number(context_menu_lat_lon.Lng(), 'f', 7), QClipboard::Clipboard); clipboard->setText(QString::number(m_context_menu_lat_lon.Lng(), 'f', 7), QClipboard::Clipboard);
} }
void OPMapGadgetWidget::onShowCompassAct_toggled(bool show) void OPMapGadgetWidget::onShowCompassAct_toggled(bool show)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->SetShowCompass(show); m_map->SetShowCompass(show);
} }
void OPMapGadgetWidget::onShowDiagnostics_toggled(bool show) void OPMapGadgetWidget::onShowDiagnostics_toggled(bool show)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->SetShowDiagnostics(show); m_map->SetShowDiagnostics(show);
} }
void OPMapGadgetWidget::onShowHomeAct_toggled(bool show) void OPMapGadgetWidget::onShowHomeAct_toggled(bool show)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->Home->setVisible(show); m_map->Home->setVisible(show);
} }
void OPMapGadgetWidget::onShowUAVAct_toggled(bool show) void OPMapGadgetWidget::onShowUAVAct_toggled(bool show)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->UAV->setVisible(show); m_map->UAV->setVisible(show);
m_map->GPS->setVisible(show); m_map->GPS->setVisible(show);
@ -1662,8 +1736,8 @@ void OPMapGadgetWidget::onShowUAVAct_toggled(bool show)
void OPMapGadgetWidget::onShowTrailAct_toggled(bool show) void OPMapGadgetWidget::onShowTrailAct_toggled(bool show)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->UAV->SetShowTrail(show); m_map->UAV->SetShowTrail(show);
m_map->GPS->SetShowTrail(show); m_map->GPS->SetShowTrail(show);
@ -1671,8 +1745,8 @@ void OPMapGadgetWidget::onShowTrailAct_toggled(bool show)
void OPMapGadgetWidget::onShowTrailLineAct_toggled(bool show) void OPMapGadgetWidget::onShowTrailLineAct_toggled(bool show)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->UAV->SetShowTrailLine(show); m_map->UAV->SetShowTrailLine(show);
m_map->GPS->SetShowTrailLine(show); m_map->GPS->SetShowTrailLine(show);
@ -1700,42 +1774,50 @@ void OPMapGadgetWidget::onGoZoomOutAct_triggered()
void OPMapGadgetWidget::onZoomActGroup_triggered(QAction *action) void OPMapGadgetWidget::onZoomActGroup_triggered(QAction *action)
{ {
if (!m_widget || !action) if (!m_widget || !m_map || !action)
return; return;
setZoom(action->data().toInt()); setZoom(action->data().toInt());
} }
void OPMapGadgetWidget::onMaxUpdateRateActGroup_triggered(QAction *action)
{
if (!m_widget || !m_map || !action)
return;
setMaxUpdateRate(action->data().toInt());
}
void OPMapGadgetWidget::onGoMouseClickAct_triggered() void OPMapGadgetWidget::onGoMouseClickAct_triggered()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->SetCurrentPosition(m_map->currentMousePosition()); // center the map onto the mouse position m_map->SetCurrentPosition(m_map->currentMousePosition()); // center the map onto the mouse position
} }
void OPMapGadgetWidget::onSetHomeAct_triggered() void OPMapGadgetWidget::onSetHomeAct_triggered()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
setHome(context_menu_lat_lon); setHome(m_context_menu_lat_lon);
setHomeLocationObject(); // update the HomeLocation UAVObject setHomeLocationObject(); // update the HomeLocation UAVObject
} }
void OPMapGadgetWidget::onGoHomeAct_triggered() void OPMapGadgetWidget::onGoHomeAct_triggered()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
goHome(); goHome();
} }
void OPMapGadgetWidget::onGoUAVAct_triggered() void OPMapGadgetWidget::onGoUAVAct_triggered()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
double latitude; double latitude;
double longitude; double longitude;
@ -1750,8 +1832,8 @@ void OPMapGadgetWidget::onGoUAVAct_triggered()
void OPMapGadgetWidget::onFollowUAVpositionAct_toggled(bool checked) void OPMapGadgetWidget::onFollowUAVpositionAct_toggled(bool checked)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
if (m_widget->toolButtonMapUAV->isChecked() != checked) if (m_widget->toolButtonMapUAV->isChecked() != checked)
m_widget->toolButtonMapUAV->setChecked(checked); m_widget->toolButtonMapUAV->setChecked(checked);
@ -1761,8 +1843,8 @@ void OPMapGadgetWidget::onFollowUAVpositionAct_toggled(bool checked)
void OPMapGadgetWidget::onFollowUAVheadingAct_toggled(bool checked) void OPMapGadgetWidget::onFollowUAVheadingAct_toggled(bool checked)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
if (m_widget->toolButtonMapUAVheading->isChecked() != checked) if (m_widget->toolButtonMapUAVheading->isChecked() != checked)
m_widget->toolButtonMapUAVheading->setChecked(checked); m_widget->toolButtonMapUAVheading->setChecked(checked);
@ -1772,8 +1854,8 @@ void OPMapGadgetWidget::onFollowUAVheadingAct_toggled(bool checked)
void OPMapGadgetWidget::onUAVTrailTypeActGroup_triggered(QAction *action) void OPMapGadgetWidget::onUAVTrailTypeActGroup_triggered(QAction *action)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map || !action)
return; return;
int trail_type_idx = action->data().toInt(); int trail_type_idx = action->data().toInt();
@ -1785,8 +1867,8 @@ void OPMapGadgetWidget::onUAVTrailTypeActGroup_triggered(QAction *action)
void OPMapGadgetWidget::onClearUAVtrailAct_triggered() void OPMapGadgetWidget::onClearUAVtrailAct_triggered()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
m_map->UAV->DeleteTrail(); m_map->UAV->DeleteTrail();
m_map->GPS->DeleteTrail(); m_map->GPS->DeleteTrail();
@ -1794,8 +1876,8 @@ void OPMapGadgetWidget::onClearUAVtrailAct_triggered()
void OPMapGadgetWidget::onUAVTrailTimeActGroup_triggered(QAction *action) void OPMapGadgetWidget::onUAVTrailTimeActGroup_triggered(QAction *action)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map || !action)
return; return;
int trail_time = (double)action->data().toInt(); int trail_time = (double)action->data().toInt();
@ -1804,8 +1886,8 @@ void OPMapGadgetWidget::onUAVTrailTimeActGroup_triggered(QAction *action)
void OPMapGadgetWidget::onUAVTrailDistanceActGroup_triggered(QAction *action) void OPMapGadgetWidget::onUAVTrailDistanceActGroup_triggered(QAction *action)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map || !action)
return; return;
int trail_distance = action->data().toInt(); int trail_distance = action->data().toInt();
@ -1818,8 +1900,8 @@ void OPMapGadgetWidget::onUAVTrailDistanceActGroup_triggered(QAction *action)
/* /*
void OPMapGadgetWidget::onAddWayPointAct_triggered() void OPMapGadgetWidget::onAddWayPointAct_triggered()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
if (m_map_mode != Normal_MapMode) if (m_map_mode != Normal_MapMode)
return; return;
@ -1866,8 +1948,8 @@ void OPMapGadgetWidget::onAddWayPointAct_triggered()
/* /*
void OPMapGadgetWidget::onEditWayPointAct_triggered() void OPMapGadgetWidget::onEditWayPointAct_triggered()
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map)
return; return;
if (m_map_mode != Normal_MapMode) if (m_map_mode != Normal_MapMode)
return; return;
@ -2010,7 +2092,7 @@ void OPMapGadgetWidget::onShowSafeAreaAct_toggled(bool show)
void OPMapGadgetWidget::onSafeAreaActGroup_triggered(QAction *action) void OPMapGadgetWidget::onSafeAreaActGroup_triggered(QAction *action)
{ {
if (!m_widget || !m_map) if (!m_widget || !m_map || !action)
return; return;
int radius = action->data().toInt(); int radius = action->data().toInt();
@ -2033,10 +2115,10 @@ void OPMapGadgetWidget::homeMagicWaypoint()
if (m_map_mode != MagicWaypoint_MapMode) if (m_map_mode != MagicWaypoint_MapMode)
return; return;
magic_waypoint.coord = home_position.coord; m_magic_waypoint.coord = m_home_position.coord;
if (magic_waypoint.map_wp_item) if (m_magic_waypoint.map_wp_item)
magic_waypoint.map_wp_item->SetCoord(magic_waypoint.coord); m_magic_waypoint.map_wp_item->SetCoord(m_magic_waypoint.coord);
} }
// ************************************************************************************* // *************************************************************************************
@ -2134,8 +2216,8 @@ void OPMapGadgetWidget::keepMagicWaypointWithInSafeArea()
{ {
// calcute the bearing and distance from the home position to the magic waypoint // calcute the bearing and distance from the home position to the magic waypoint
double dist = distance(home_position.coord, magic_waypoint.coord); double dist = distance(m_home_position.coord, m_magic_waypoint.coord);
double bear = bearing(home_position.coord, magic_waypoint.coord); double bear = bearing(m_home_position.coord, m_magic_waypoint.coord);
// get the maximum safe distance - in kilometers // get the maximum safe distance - in kilometers
double boundry_dist = (double)m_map->Home->SafeArea() / 1000; double boundry_dist = (double)m_map->Home->SafeArea() / 1000;
@ -2147,12 +2229,12 @@ void OPMapGadgetWidget::keepMagicWaypointWithInSafeArea()
// move the magic waypoint // move the magic waypoint
magic_waypoint.coord = destPoint(home_position.coord, bear, dist); m_magic_waypoint.coord = destPoint(m_home_position.coord, bear, dist);
if (m_map_mode == MagicWaypoint_MapMode) if (m_map_mode == MagicWaypoint_MapMode)
{ // move the on-screen waypoint { // move the on-screen waypoint
if (magic_waypoint.map_wp_item) if (m_magic_waypoint.map_wp_item)
magic_waypoint.map_wp_item->SetCoord(magic_waypoint.coord); m_magic_waypoint.map_wp_item->SetCoord(m_magic_waypoint.coord);
} }
} }
@ -2289,7 +2371,21 @@ bool OPMapGadgetWidget::getUAVPosition(double &latitude, double &longitude, doub
return true; return true;
} }
// ************************************************************************************* double OPMapGadgetWidget::getUAV_Yaw()
{
if (!obm)
return 0;
UAVObject *obj = dynamic_cast<UAVDataObject*>(obm->getObject(QString("AttitudeActual")));
double yaw = obj->getField(QString("Yaw"))->getDouble();
if (yaw != yaw) yaw = 0; // nan detection
while (yaw < 0) yaw += 360;
while (yaw >= 360) yaw -= 360;
return yaw;
}
bool OPMapGadgetWidget::getGPSPosition(double &latitude, double &longitude, double &altitude) bool OPMapGadgetWidget::getGPSPosition(double &latitude, double &longitude, double &altitude)
{ {
@ -2308,22 +2404,6 @@ bool OPMapGadgetWidget::getGPSPosition(double &latitude, double &longitude, doub
return true; return true;
} }
double OPMapGadgetWidget::getUAV_Yaw()
{
if (!obm)
return 0;
UAVObject *obj = dynamic_cast<UAVDataObject*>(obm->getObject(QString("AttitudeActual")));
double yaw = obj->getField(QString("Yaw"))->getDouble();
if (yaw != yaw) yaw = 0; // nan detection
while (yaw < 0) yaw += 360;
while (yaw >= 360) yaw -= 360;
return yaw;
}
// ************************************************************************************* // *************************************************************************************
void OPMapGadgetWidget::setMapFollowingMode() void OPMapGadgetWidget::setMapFollowingMode()
@ -2359,7 +2439,7 @@ bool OPMapGadgetWidget::setHomeLocationObject()
if (!obum) if (!obum)
return false; return false;
double LLA[3] = {home_position.coord.Lat(), home_position.coord.Lng(), home_position.altitude}; double LLA[3] = {m_home_position.coord.Lat(), m_home_position.coord.Lng(), m_home_position.altitude};
return (obum->setHomeLocation(LLA, true) >= 0); return (obum->setHomeLocation(LLA, true) >= 0);
} }

View File

@ -115,7 +115,8 @@ public:
void setUseMemoryCache(bool useMemoryCache); void setUseMemoryCache(bool useMemoryCache);
void setCacheLocation(QString cacheLocation); void setCacheLocation(QString cacheLocation);
void setMapMode(opMapModeType mode); void setMapMode(opMapModeType mode);
void SetUavPic(QString UAVPic); void SetUavPic(QString UAVPic);
void setMaxUpdateRate(int update_rate);
public slots: public slots:
void homePositionUpdated(UAVObject *); void homePositionUpdated(UAVObject *);
@ -221,25 +222,31 @@ private slots:
void onClearUAVtrailAct_triggered(); void onClearUAVtrailAct_triggered();
void onUAVTrailTimeActGroup_triggered(QAction *action); void onUAVTrailTimeActGroup_triggered(QAction *action);
void onUAVTrailDistanceActGroup_triggered(QAction *action); void onUAVTrailDistanceActGroup_triggered(QAction *action);
void onMaxUpdateRateActGroup_triggered(QAction *action);
private: private:
int min_zoom;
int max_zoom; // *****
int m_min_zoom;
int m_max_zoom;
double m_heading; // uav heading double m_heading; // uav heading
internals::PointLatLng mouse_lat_lon; internals::PointLatLng m_mouse_lat_lon;
internals::PointLatLng context_menu_lat_lon; internals::PointLatLng m_context_menu_lat_lon;
int prev_tile_number; int m_prev_tile_number;
opMapModeType m_map_mode; opMapModeType m_map_mode;
t_home home_position; int m_maxUpdateRate;
t_waypoint magic_waypoint; t_home m_home_position;
QStringList findPlaceWordList; t_waypoint m_magic_waypoint;
QStringList findPlaceWordList;
QCompleter *findPlaceCompleter; QCompleter *findPlaceCompleter;
QTimer *m_updateTimer; QTimer *m_updateTimer;
@ -266,14 +273,16 @@ private:
QMutex m_map_mutex; QMutex m_map_mutex;
bool telemetry_connected; bool m_telemetry_connected;
// *****
void createActions(); void createActions();
QAction *closeAct1; QAction *closeAct1;
QAction *closeAct2; QAction *closeAct2;
QAction *reloadAct; QAction *reloadAct;
QAction *copyMouseLatLonToClipAct; QAction *copyMouseLatLonToClipAct;
QAction *copyMouseLatToClipAct; QAction *copyMouseLatToClipAct;
QAction *copyMouseLonToClipAct; QAction *copyMouseLonToClipAct;
QAction *findPlaceAct; QAction *findPlaceAct;
@ -319,7 +328,12 @@ private:
QActionGroup *zoomActGroup; QActionGroup *zoomActGroup;
QList<QAction *> zoomAct; QList<QAction *> zoomAct;
void homeMagicWaypoint(); QActionGroup *maxUpdateRateActGroup;
QList<QAction *> maxUpdateRateAct;
// *****
void homeMagicWaypoint();
void moveToMagicWaypointPosition(); void moveToMagicWaypointPosition();

View File

@ -151,6 +151,16 @@ void SystemHealthGadgetWidget::setSystemFile(QString dfn)
QGraphicsScene *l_scene = scene(); QGraphicsScene *l_scene = scene();
l_scene->setSceneRect(background->boundingRect()); l_scene->setSceneRect(background->boundingRect());
fitInView(background, Qt::KeepAspectRatio ); fitInView(background, Qt::KeepAspectRatio );
// Check whether the autopilot is connected already, by the way:
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
TelemetryManager* telMngr = pm->getObject<TelemetryManager>();
if (telMngr->isConnected()) {
onAutopilotConnect();
SystemAlarms* obj = dynamic_cast<SystemAlarms*>(objManager->getObject(QString("SystemAlarms")));
updateAlarms(obj);
}
} }
} }
else else

View File

@ -4,7 +4,7 @@
<field name="AccelBias" units="lsb" type="int16" elementnames="X,Y,Z" defaultvalue="0"/> <field name="AccelBias" units="lsb" type="int16" elementnames="X,Y,Z" defaultvalue="0"/>
<field name="BoardRotation" units="deg" type="int8" elementnames="Roll,Pitch,Yaw" defaultvalue="0,0,0"/> <field name="BoardRotation" units="deg" type="int8" elementnames="Roll,Pitch,Yaw" defaultvalue="0,0,0"/>
<field name="GyroGain" units="(rad/s)/lsb" type="float" elements="1" defaultvalue="0.42"/> <field name="GyroGain" units="(rad/s)/lsb" type="float" elements="1" defaultvalue="0.42"/>
<field name="AccelKp" units="channel" type="float" elements="1" defaultvalue="0.01"/> <field name="AccelKp" units="channel" type="float" elements="1" defaultvalue="0.05"/>
<field name="AccelKi" units="channel" type="float" elements="1" defaultvalue="0.0001"/> <field name="AccelKi" units="channel" type="float" elements="1" defaultvalue="0.0001"/>
<field name="YawBiasRate" units="channel" type="float" elements="1" defaultvalue="0.000001"/> <field name="YawBiasRate" units="channel" type="float" elements="1" defaultvalue="0.000001"/>
<field name="ZeroDuringArming" units="channel" type="enum" elements="1" options="FALSE,TRUE" defaultvalue="FALSE"/> <field name="ZeroDuringArming" units="channel" type="enum" elements="1" options="FALSE,TRUE" defaultvalue="FALSE"/>

View File

@ -7,9 +7,9 @@
<field name="ManualRate" units="degrees/sec" type="float" elementnames="Roll,Pitch,Yaw" defaultvalue="150,150,150"/> <field name="ManualRate" units="degrees/sec" type="float" elementnames="Roll,Pitch,Yaw" defaultvalue="150,150,150"/>
<field name="MaximumRate" units="degrees/sec" type="float" elementnames="Roll,Pitch,Yaw" defaultvalue="300,300,300"/> <field name="MaximumRate" units="degrees/sec" type="float" elementnames="Roll,Pitch,Yaw" defaultvalue="300,300,300"/>
<field name="RollRatePI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="0.0015,0,0.3"/> <field name="RollRatePI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="0.002,0,0.3"/>
<field name="PitchRatePI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="0.0015,0,0.3"/> <field name="PitchRatePI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="0.002,0,0.3"/>
<field name="YawRatePI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="0.003,0,0.3"/> <field name="YawRatePI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="0.003,0.003,0.3"/>
<field name="RollPI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="2,0,50"/> <field name="RollPI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="2,0,50"/>
<field name="PitchPI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="2,0,50"/> <field name="PitchPI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="2,0,50"/>
<field name="YawPI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="2,0,50"/> <field name="YawPI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="2,0,50"/>