1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

Merge branch 'CorvusCorax_unidirectional-GPS-com' into CC_GPS

Conflicts:
	flight/Modules/GPS/GPS.c
	flight/Modules/GPS/GTOP_BIN.c
	flight/Modules/GPS/NMEA.c
	shared/uavobjectdefinition/hwsettings.xml
This commit is contained in:
Corvus Corax 2011-08-25 15:33:23 +02:00
commit 4bd72923e5
24 changed files with 1095 additions and 1353 deletions

View File

@ -924,6 +924,8 @@ void PIOS_Board_Init(void) {
TaskMonitorInitialize(); TaskMonitorInitialize();
/* Configure the main IO port */ /* Configure the main IO port */
uint8_t hwsettings_DSMxBind;
HwSettingsDSMxBindGet(&hwsettings_DSMxBind);
uint8_t hwsettings_cc_mainport; uint8_t hwsettings_cc_mainport;
HwSettingsCC_MainPortGet(&hwsettings_cc_mainport); HwSettingsCC_MainPortGet(&hwsettings_cc_mainport);
@ -992,7 +994,7 @@ void PIOS_Board_Init(void) {
} }
uint32_t pios_spektrum_id; uint32_t pios_spektrum_id;
if (PIOS_SPEKTRUM_Init(&pios_spektrum_id, &pios_spektrum_main_cfg, &pios_usart_com_driver, pios_usart_spektrum_id, false)) { if (PIOS_SPEKTRUM_Init(&pios_spektrum_id, &pios_spektrum_main_cfg, &pios_usart_com_driver, pios_usart_spektrum_id, 0)) {
PIOS_Assert(0); PIOS_Assert(0);
} }
} }
@ -1056,7 +1058,7 @@ void PIOS_Board_Init(void) {
} }
uint32_t pios_spektrum_id; uint32_t pios_spektrum_id;
if (PIOS_SPEKTRUM_Init(&pios_spektrum_id, &pios_spektrum_flexi_cfg, &pios_usart_com_driver, pios_usart_spektrum_id, false)) { if (PIOS_SPEKTRUM_Init(&pios_spektrum_id, &pios_spektrum_flexi_cfg, &pios_usart_com_driver, pios_usart_spektrum_id, hwsettings_DSMxBind)) {
PIOS_Assert(0); PIOS_Assert(0);
} }
} }

View File

@ -35,17 +35,12 @@
#include <stdbool.h> #include <stdbool.h>
#ifdef ENABLE_GPS_BINARY_GTOP #include "NMEA.h"
#include "GTOP_BIN.h"
#endif
#if defined(ENABLE_GPS_ONESENTENCE_GTOP) || defined(ENABLE_GPS_NMEA)
#include "NMEA.h"
#endif
#include "gpsposition.h" #include "gpsposition.h"
#include "homelocation.h" #include "homelocation.h"
#include "gpstime.h" #include "gpstime.h"
#include "gpssatellites.h"
#include "WorldMagModel.h" #include "WorldMagModel.h"
#include "CoordinateConversions.h" #include "CoordinateConversions.h"
@ -62,25 +57,16 @@ 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 DISABLE_GPS_THRESHOLD //
#define GPS_TIMEOUT_MS 500 #define GPS_TIMEOUT_MS 500
#define GPS_COMMAND_RESEND_TIMEOUT_MS 2000 #define NMEA_MAX_PACKET_LENGTH 96 // 82 max NMEA msg size plus 12 margin (because some vendors add custom crap) plus CR plus Linefeed
// same as in COM buffer
#ifdef PIOS_GPS_SETS_HOMELOCATION #ifdef PIOS_GPS_SETS_HOMELOCATION
// Unfortunately need a good size stack for the WMM calculation // Unfortunately need a good size stack for the WMM calculation
#ifdef ENABLE_GPS_BINARY_GTOP #define STACK_SIZE_BYTES 800
#define STACK_SIZE_BYTES 800
#else
#define STACK_SIZE_BYTES 800
#endif
#else #else
#ifdef ENABLE_GPS_BINARY_GTOP #define STACK_SIZE_BYTES 650
#define STACK_SIZE_BYTES 650
#else
#define STACK_SIZE_BYTES 650
#endif
#endif #endif
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1) #define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
@ -92,9 +78,7 @@ static uint32_t gpsPort;
static xTaskHandle gpsTaskHandle; static xTaskHandle gpsTaskHandle;
#ifndef ENABLE_GPS_BINARY_GTOP static char* gps_rx_buffer;
static char gps_rx_buffer[128];
#endif
static uint32_t timeOfLastCommandMs; static uint32_t timeOfLastCommandMs;
static uint32_t timeOfLastUpdateMs; static uint32_t timeOfLastUpdateMs;
@ -127,12 +111,17 @@ int32_t GPSInitialize(void)
GPSPositionInitialize(); GPSPositionInitialize();
#if !defined(PIOS_GPS_PURISTIC) #if !defined(PIOS_GPS_PURISTIC)
GPSTimeInitialize(); GPSTimeInitialize();
GPSSatellitesInitialize();
#ifdef PIOS_GPS_SETS_HOMELOCATION
HomeLocationInitialize(); HomeLocationInitialize();
#endif #endif
// TODO: Get gps settings object // TODO: Get gps settings object
gpsPort = PIOS_COM_GPS; gpsPort = PIOS_COM_GPS;
gps_rx_buffer = pvPortMalloc(NMEA_MAX_PACKET_LENGTH);
PIOS_Assert(gps_rx_buffer);
return 0; return 0;
} }
// optional module, gets initialized separately // optional module, gets initialized separately
@ -149,44 +138,10 @@ static void gpsTask(void *parameters)
uint32_t timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS;; uint32_t timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS;;
GPSPositionData GpsData; GPSPositionData GpsData;
#ifdef ENABLE_GPS_BINARY_GTOP
GTOP_BIN_init();
#else
uint8_t rx_count = 0; uint8_t rx_count = 0;
bool start_flag = false; bool start_flag = false;
bool found_cr = false; bool found_cr = false;
int32_t gpsRxOverflow = 0; int32_t gpsRxOverflow = 0;
#endif
#ifdef FULL_COLD_RESTART
// tell the GPS to do a FULL COLD restart
PIOS_COM_SendStringNonBlocking(gpsPort, "$PMTK104*37\r\n");
timeOfLastCommandMs = timeNowMs;
while (timeNowMs - timeOfLastCommandMs < 300) // delay for 300ms to let the GPS sort itself out
{
vTaskDelay(xDelay); // Block task until next update
timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS;;
}
#endif
#ifdef DISABLE_GPS_THRESHOLD
PIOS_COM_SendStringNonBlocking(gpsPort, "$PMTK397,0*23\r\n");
#endif
#ifdef ENABLE_GPS_BINARY_GTOP
// switch to GTOP binary mode
PIOS_COM_SendStringNonBlocking(gpsPort ,"$PGCMD,21,1*6F\r\n");
#endif
#ifdef ENABLE_GPS_ONESENTENCE_GTOP
// switch to single sentence mode
PIOS_COM_SendStringNonBlocking(gpsPort, "$PGCMD,21,2*6C\r\n");
#endif
#ifdef ENABLE_GPS_NMEA
// switch to NMEA mode
PIOS_COM_SendStringNonBlocking(gpsPort, "$PGCMD,21,3*6D\r\n");
#endif
numUpdates = 0; numUpdates = 0;
numChecksumErrors = 0; numChecksumErrors = 0;
@ -198,108 +153,87 @@ static void gpsTask(void *parameters)
// Loop forever // Loop forever
while (1) while (1)
{ {
#ifdef ENABLE_GPS_BINARY_GTOP uint8_t c;
// GTOP BINARY GPS mode // NMEA or SINGLE-SENTENCE GPS mode
while (PIOS_COM_ReceiveBufferUsed(gpsPort) > 0) // This blocks the task until there is something on the buffer
while (PIOS_COM_ReceiveBuffer(gpsPort, &c, 1, xDelay) > 0)
{
// detect start while acquiring stream
if (!start_flag && (c == '$'))
{ {
uint8_t c; start_flag = true;
PIOS_COM_ReceiveBuffer(gpsPort, &c, 1, 0); found_cr = false;
rx_count = 0;
}
else
if (!start_flag)
continue;
if (GTOP_BIN_update_position(c, &numChecksumErrors, &numParsingErrors) >= 0) if (rx_count >= NMEA_MAX_PACKET_LENGTH)
{ {
numUpdates++; // The buffer is already full and we haven't found a valid NMEA sentence.
// Flush the buffer and note the overflow event.
gpsRxOverflow++;
start_flag = false;
found_cr = false;
rx_count = 0;
}
else
{
gps_rx_buffer[rx_count] = c;
rx_count++;
}
// look for ending '\r\n' sequence
if (!found_cr && (c == '\r') )
found_cr = true;
else
if (found_cr && (c != '\n') )
found_cr = false; // false end flag
else
if (found_cr && (c == '\n') )
{
// The NMEA functions require a zero-terminated string
// As we detected \r\n, the string as for sure 2 bytes long, we will also strip the \r\n
gps_rx_buffer[rx_count-2] = 0;
// prepare to parse next sentence
start_flag = false;
found_cr = false;
rx_count = 0;
// Our rxBuffer must look like this now:
// [0] = '$'
// ... = zero or more bytes of sentence payload
// [end_pos - 1] = '\r'
// [end_pos] = '\n'
//
// Prepare to consume the sentence from the buffer
// Validate the checksum over the sentence
if (!NMEA_checksum(&gps_rx_buffer[1]))
{ // Invalid checksum. May indicate dropped characters on Rx.
//PIOS_DEBUG_PinHigh(2);
++numChecksumErrors;
//PIOS_DEBUG_PinLow(2);
}
else
{ // Valid checksum, use this packet to update the GPS position
if (!NMEA_update_position(&gps_rx_buffer[1])) {
//PIOS_DEBUG_PinHigh(2);
++numParsingErrors;
//PIOS_DEBUG_PinLow(2);
}
else
++numUpdates;
timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS; timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS;
timeOfLastUpdateMs = timeNowMs; timeOfLastUpdateMs = timeNowMs;
timeOfLastCommandMs = timeNowMs; timeOfLastCommandMs = timeNowMs;
} }
} }
}
#else
// NMEA or SINGLE-SENTENCE GPS mode
// This blocks the task until there is something on the buffer
while (PIOS_COM_ReceiveBufferUsed(gpsPort) > 0)
{
uint8_t c;
PIOS_COM_ReceiveBuffer(gpsPort, &c, 1, 0);
// detect start while acquiring stream
if (!start_flag && (c == '$'))
{
start_flag = true;
found_cr = false;
rx_count = 0;
}
else
if (!start_flag)
continue;
if (rx_count >= sizeof(gps_rx_buffer))
{
// The buffer is already full and we haven't found a valid NMEA sentence.
// Flush the buffer and note the overflow event.
gpsRxOverflow++;
start_flag = false;
found_cr = false;
rx_count = 0;
}
else
{
gps_rx_buffer[rx_count] = c;
rx_count++;
}
// look for ending '\r\n' sequence
if (!found_cr && (c == '\r') )
found_cr = true;
else
if (found_cr && (c != '\n') )
found_cr = false; // false end flag
else
if (found_cr && (c == '\n') )
{
// The NMEA functions require a zero-terminated string
// As we detected \r\n, the string as for sure 2 bytes long, we will also strip the \r\n
gps_rx_buffer[rx_count-2] = 0;
// prepare to parse next sentence
start_flag = false;
found_cr = false;
rx_count = 0;
// Our rxBuffer must look like this now:
// [0] = '$'
// ... = zero or more bytes of sentence payload
// [end_pos - 1] = '\r'
// [end_pos] = '\n'
//
// Prepare to consume the sentence from the buffer
// Validate the checksum over the sentence
if (!NMEA_checksum(&gps_rx_buffer[1]))
{ // Invalid checksum. May indicate dropped characters on Rx.
//PIOS_DEBUG_PinHigh(2);
++numChecksumErrors;
//PIOS_DEBUG_PinLow(2);
}
else
{ // Valid checksum, use this packet to update the GPS position
if (!NMEA_update_position(&gps_rx_buffer[1])) {
//PIOS_DEBUG_PinHigh(2);
++numParsingErrors;
//PIOS_DEBUG_PinLow(2);
}
else
++numUpdates;
timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS;
timeOfLastUpdateMs = timeNowMs;
timeOfLastCommandMs = timeNowMs;
}
}
}
#endif
// Check for GPS timeout // Check for GPS timeout
timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS; timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS;
@ -312,30 +246,6 @@ static void gpsTask(void *parameters)
GPSPositionSet(&GpsData); GPSPositionSet(&GpsData);
AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_ERROR); AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_ERROR);
if ((timeNowMs - timeOfLastCommandMs) >= GPS_COMMAND_RESEND_TIMEOUT_MS)
{ // resend the command .. just incase the gps has only just been plugged in or the gps did not get our last command
timeOfLastCommandMs = timeNowMs;
#ifdef ENABLE_GPS_BINARY_GTOP
GTOP_BIN_init();
// switch to binary mode
PIOS_COM_SendStringNonBlocking(gpsPort,"$PGCMD,21,1*6F\r\n");
#endif
#ifdef ENABLE_GPS_ONESENTENCE_GTOP
// switch to single sentence mode
PIOS_COM_SendStringNonBlocking(gpsPort,"$PGCMD,21,2*6C\r\n");
#endif
#ifdef ENABLE_GPS_NMEA
// switch to NMEA mode
PIOS_COM_SendStringNonBlocking(gpsPort,"$PGCMD,21,3*6D\r\n");
#endif
#ifdef DISABLE_GPS_TRESHOLD
PIOS_COM_SendStringNonBlocking(gpsPort,"$PMTK397,0*23\r\n");
#endif
}
} }
else else
{ // we appear to be receiving GPS sentences OK, we've had an update { // we appear to be receiving GPS sentences OK, we've had an update
@ -361,8 +271,6 @@ static void gpsTask(void *parameters)
AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_CRITICAL); AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_CRITICAL);
} }
// Block task until next update
vTaskDelay(xDelay);
} }
} }

View File

@ -1,266 +0,0 @@
/**
******************************************************************************
* @addtogroup OpenPilotModules OpenPilot Modules
* @{
* @addtogroup GSPModule GPS Module
* @brief Process GPS information
* @{
*
* @file GTOP_BIN.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief GPS module, handles GPS and NMEA stream
* @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 "pios.h"
#include "GTOP_BIN.h"
#include "gpsposition.h"
#include "gpstime.h"
#include "gpssatellites.h"
#include <string.h> // memmove
#ifdef ENABLE_GPS_BINARY_GTOP
// ************
// the structure of the binary packet
typedef struct
{
uint32_t utc_time;
int32_t latitude;
uint8_t ns_indicator;
int32_t longitude;
uint8_t ew_indicator;
uint8_t fix_quality;
uint8_t satellites_used;
uint16_t hdop;
int32_t msl_altitude;
int32_t geoidal_seperation;
uint8_t fix_type;
int32_t course_over_ground;
int32_t speed_over_ground;
uint8_t day;
uint8_t month;
uint16_t year;
} __attribute__((__packed__)) t_gps_bin_packet_data;
typedef struct
{
uint16_t header;
t_gps_bin_packet_data data;
uint8_t asterisk;
uint8_t checksum;
uint16_t end_word;
} __attribute__((__packed__)) t_gps_bin_packet;
// ************
// buffer that holds the incoming binary packet
static uint8_t gps_rx_buffer[sizeof(t_gps_bin_packet)] __attribute__ ((aligned(4)));
// number of bytes currently in the rx buffer
static int16_t gps_rx_buffer_wr = 0;
// ************
// endian swapping functions
static uint16_t swap2Bytes(uint16_t data)
{
return (((data >> 8) & 0x00ff) |
((data << 8) & 0xff00));
}
static uint32_t swap4Bytes(uint32_t data)
{
return (((data >> 24) & 0x000000ff) |
((data >> 8) & 0x0000ff00) |
((data << 8) & 0x00ff0000) |
((data << 24) & 0xff000000));
}
// ************
/**
* Parses a complete binary packet and update the GPSPosition and GPSTime UAVObjects
*
* param[in] .. b = a new received byte from the GPS
*
* return '0' if we have found a valid binary packet
* return <0 if any errors were encountered with the packet or no packet found
*/
int GTOP_BIN_update_position(uint8_t b, volatile uint32_t *chksum_errors, volatile uint32_t *parsing_errors)
{
if (gps_rx_buffer_wr >= sizeof(gps_rx_buffer))
{ // make room for the new byte .. this will actually never get executed, just here as a safe guard really
memmove(gps_rx_buffer, gps_rx_buffer + 1, sizeof(gps_rx_buffer) - 1);
gps_rx_buffer_wr = sizeof(gps_rx_buffer) - 1;
}
// add the new byte into the buffer
gps_rx_buffer[gps_rx_buffer_wr++] = b;
int16_t i = 0;
while (gps_rx_buffer_wr > 0)
{
t_gps_bin_packet *rx_packet = (t_gps_bin_packet *)(gps_rx_buffer + i);
// scan for the start of a binary packet (the header bytes)
while (gps_rx_buffer_wr - i >= sizeof(rx_packet->header))
{
if (rx_packet->header == 0x2404)
break; // found a valid header marker
rx_packet = (t_gps_bin_packet *)(gps_rx_buffer + ++i);
}
// remove unwanted bytes before the start of the packet header
if (i > 0)
{
gps_rx_buffer_wr -= i;
if (gps_rx_buffer_wr > 0)
memmove(gps_rx_buffer, gps_rx_buffer + i, gps_rx_buffer_wr);
i = 0;
}
if (gps_rx_buffer_wr < sizeof(t_gps_bin_packet))
break; // not yet enough bytes for a complete binary packet
// we have enough bytes for a complete binary packet
// check to see if certain parameters in the binary packet are valid
if (rx_packet->header != 0x2404 ||
rx_packet->end_word != 0x0A0D ||
rx_packet->asterisk != 0x2A ||
(rx_packet->data.ns_indicator != 1 && rx_packet->data.ns_indicator != 2) ||
(rx_packet->data.ew_indicator != 1 && rx_packet->data.ew_indicator != 2) ||
(rx_packet->data.fix_quality > 2) ||
(rx_packet->data.fix_type < 1 || rx_packet->data.fix_type > 3) )
{ // invalid packet
if (parsing_errors) *parsing_errors++;
i++;
continue;
}
{ // check the checksum is valid
uint8_t *p = (uint8_t *)&rx_packet->data;
uint8_t checksum = 0;
for (int i = 0; i < sizeof(t_gps_bin_packet_data); i++)
checksum ^= *p++;
if (checksum != rx_packet->checksum)
{ // checksum error
if (chksum_errors) *chksum_errors++;
i++;
continue;
}
}
// we now have a valid complete binary packet, update the GpsData and GpsTime objects
// correct the endian order of the parameters
rx_packet->data.utc_time = swap4Bytes(rx_packet->data.utc_time);
rx_packet->data.latitude = swap4Bytes(rx_packet->data.latitude);
rx_packet->data.longitude = swap4Bytes(rx_packet->data.longitude);
rx_packet->data.hdop = swap2Bytes(rx_packet->data.hdop);
rx_packet->data.msl_altitude = swap4Bytes(rx_packet->data.msl_altitude);
rx_packet->data.geoidal_seperation = swap4Bytes(rx_packet->data.geoidal_seperation);
rx_packet->data.course_over_ground = swap4Bytes(rx_packet->data.course_over_ground);
rx_packet->data.speed_over_ground = swap4Bytes(rx_packet->data.speed_over_ground);
rx_packet->data.year = swap2Bytes(rx_packet->data.year);
#if !defined(PIOS_GPS_PURISTIC)
// set the gps time object
GPSTimeData GpsTime;
// GPSTimeGet(&GpsTime);
uint32_t utc_time = rx_packet->data.utc_time / 1000;
GpsTime.Second = utc_time % 100; // seconds
GpsTime.Minute = (utc_time / 100) % 100; // minutes
GpsTime.Hour = utc_time / 10000; // hours
GpsTime.Day = rx_packet->data.day; // day
GpsTime.Month = rx_packet->data.month; // month
GpsTime.Year = rx_packet->data.year; // year
GPSTimeSet(&GpsTime);
#endif //PIOS_GPS_PURISTIC
// set the gps position object
GPSPositionData GpsData;
// GPSPositionGet(&GpsData);
switch (rx_packet->data.fix_type)
{
case 1: GpsData.Status = GPSPOSITION_STATUS_NOFIX; break;
case 2: GpsData.Status = GPSPOSITION_STATUS_FIX2D; break;
case 3: GpsData.Status = GPSPOSITION_STATUS_FIX3D; break;
default: GpsData.Status = GPSPOSITION_STATUS_NOGPS; break;
}
GpsData.Latitude = rx_packet->data.latitude * (rx_packet->data.ns_indicator == 1 ? +1 : -1) * 10; // degrees * 10e6
GpsData.Longitude = rx_packet->data.longitude * (rx_packet->data.ew_indicator == 1 ? +1 : -1) * 10; // degrees * 10e6
GpsData.Altitude = (float)rx_packet->data.msl_altitude / 1000; // meters
GpsData.GeoidSeparation = (float)rx_packet->data.geoidal_seperation / 1000; // meters
GpsData.Heading = (float)rx_packet->data.course_over_ground / 1000; // degrees
GpsData.Groundspeed = (float)rx_packet->data.speed_over_ground / 3600; // m/s
GpsData.Satellites = rx_packet->data.satellites_used; //
GpsData.PDOP = 99.99; // not available in binary mode
GpsData.HDOP = (float)rx_packet->data.hdop / 100; //
GpsData.VDOP = 99.99; // not available in binary mode
GPSPositionSet(&GpsData);
#if !defined(PIOS_GPS_PURISTIC)
// set the number of satellites
// GPSSatellitesData SattelliteData;
//// GPSSatellitesGet(&SattelliteData);
// memset(&SattelliteData, 0, sizeof(SattelliteData));
// SattelliteData.SatsInView = rx_packet->data.satellites_used; //
// GPSSatellitesSet(&SattelliteData);
#endif //PIOS_GPS_PURISTIC
// remove the spent binary packet from the buffer
gps_rx_buffer_wr -= sizeof(t_gps_bin_packet);
if (gps_rx_buffer_wr > 0)
memmove(gps_rx_buffer, gps_rx_buffer + sizeof(t_gps_bin_packet), gps_rx_buffer_wr);
return 0; // found a valid packet
}
return -1; // no valid packet found
}
// ************
void GTOP_BIN_init(void)
{
gps_rx_buffer_wr = 0;
}
// ************
#endif // ENABLE_GPS_BINARY_GTOP

View File

@ -40,8 +40,6 @@
#if defined(ENABLE_GPS_NMEA) || defined(ENABLE_GPS_ONESENTENCE_GTOP)
// Debugging // Debugging
#ifdef ENABLE_DEBUG_MSG #ifdef ENABLE_DEBUG_MSG
//#define DEBUG_MSG_IN ///< define to display the incoming NMEA messages //#define DEBUG_MSG_IN ///< define to display the incoming NMEA messages
@ -54,7 +52,6 @@
//#define NMEA_DEBUG_GSA ///< define to enable debug of GSA messages //#define NMEA_DEBUG_GSA ///< define to enable debug of GSA messages
//#define NMEA_DEBUG_GSV ///< define to enable debug of GSV messages //#define NMEA_DEBUG_GSV ///< define to enable debug of GSV messages
//#define NMEA_DEBUG_ZDA ///< define to enable debug of ZDA messages //#define NMEA_DEBUG_ZDA ///< define to enable debug of ZDA messages
//#define NMEA_DEBUG_PGTOP ///< define to enable debug of PGTOP messages
#define DEBUG_MSG(format, ...) PIOS_COM_SendFormattedString(DEBUG_PORT, format, ## __VA_ARGS__) #define DEBUG_MSG(format, ...) PIOS_COM_SendFormattedString(DEBUG_PORT, format, ## __VA_ARGS__)
#else #else
#define DEBUG_MSG(format, ...) #define DEBUG_MSG(format, ...)
@ -69,60 +66,49 @@ struct nmea_parser {
uint32_t cnt; uint32_t cnt;
}; };
#ifdef ENABLE_GPS_NMEA static bool nmeaProcessGPGGA(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam);
static bool nmeaProcessGPGGA(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam); static bool nmeaProcessGPRMC(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam);
static bool nmeaProcessGPRMC(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam); static bool nmeaProcessGPVTG(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam);
static bool nmeaProcessGPVTG(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam); static bool nmeaProcessGPGSA(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam);
static bool nmeaProcessGPGSA(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam);
#if !defined(PIOS_GPS_PURISTIC) #if !defined(PIOS_GPS_PURISTIC)
static bool nmeaProcessGPZDA(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam); static bool nmeaProcessGPZDA(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam);
static bool nmeaProcessGPGSV(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam); static bool nmeaProcessGPGSV(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam);
#endif //PIOS_GPS_PURISTIC #endif //PIOS_GPS_PURISTIC
#endif
static bool nmeaProcessPGTOP(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam);
static struct nmea_parser nmea_parsers[] = { static struct nmea_parser nmea_parsers[] = {
{
#ifdef ENABLE_GPS_NMEA .prefix = "GPGGA",
{ .handler = nmeaProcessGPGGA,
.prefix = "GPGGA", .cnt = 0,
.handler = nmeaProcessGPGGA, },
.cnt = 0, {
}, .prefix = "GPVTG",
{ .handler = nmeaProcessGPVTG,
.prefix = "GPVTG", .cnt = 0,
.handler = nmeaProcessGPVTG, },
.cnt = 0, {
}, .prefix = "GPGSA",
{ .handler = nmeaProcessGPGSA,
.prefix = "GPGSA", .cnt = 0,
.handler = nmeaProcessGPGSA, },
.cnt = 0, {
}, .prefix = "GPRMC",
{ .handler = nmeaProcessGPRMC,
.prefix = "GPRMC", .cnt = 0,
.handler = nmeaProcessGPRMC, },
.cnt = 0,
},
#if !defined(PIOS_GPS_PURISTIC) #if !defined(PIOS_GPS_PURISTIC)
{ {
.prefix = "GPZDA", .prefix = "GPZDA",
.handler = nmeaProcessGPZDA, .handler = nmeaProcessGPZDA,
.cnt = 0, .cnt = 0,
}, },
{ {
.prefix = "GPGSV", .prefix = "GPGSV",
.handler = nmeaProcessGPGSV, .handler = nmeaProcessGPGSV,
.cnt = 0, .cnt = 0,
}, },
#endif //PIOS_GPS_PURISTIC #endif //PIOS_GPS_PURISTIC
#endif
{
.prefix = "PGTOP",
.handler = nmeaProcessPGTOP,
.cnt = 0,
},
}; };
static struct nmea_parser *NMEA_find_parser_by_prefix(const char *prefix) static struct nmea_parser *NMEA_find_parser_by_prefix(const char *prefix)
@ -233,7 +219,6 @@ static float NMEA_real_to_float(char *nmea_real)
return (((float)whole) + fract * pow(10, -fract_units)); return (((float)whole) + fract * pow(10, -fract_units));
} }
#ifdef ENABLE_GPS_NMEA
/* /*
* Parse a field in the format: * Parse a field in the format:
* DD[D]MM.mmmm[mm] * DD[D]MM.mmmm[mm]
@ -291,7 +276,6 @@ static bool NMEA_latlon_to_fixed_point(int32_t * latlon, char *nmea_latlon, bool
return true; return true;
} }
#endif // ENABLE_GPS_NMEA
/** /**
@ -380,7 +364,6 @@ bool NMEA_update_position(char *nmea_sentence)
return true; return true;
} }
#ifdef ENABLE_GPS_NMEA
/** /**
* Parse an NMEA GPGGA sentence and update the given UAVObject * Parse an NMEA GPGGA sentence and update the given UAVObject
@ -685,87 +668,3 @@ static bool nmeaProcessGPGSA(GPSPositionData * GpsData, bool* gpsDataUpdated, ch
return true; return true;
} }
#endif // ENABLE_GPS_NMEA
/**
* Parse an NMEA PGTOP sentence and update the given UAVObject
* \param[in] A pointer to a GPSPosition UAVObject to be updated.
* \param[in] An NMEA sentence with a valid checksum
*/
static bool nmeaProcessPGTOP(GPSPositionData * GpsData, bool* gpsDataUpdated, char* param[], uint8_t nbParam)
{
if (nbParam != 17)
return false;
*gpsDataUpdated = true;
#if !defined(PIOS_GPS_PURISTIC)
GPSTimeData gpst;
GPSTimeGet(&gpst);
// get UTC time [hhmmss.sss]
float hms = NMEA_real_to_float(param[1]);
gpst.Second = (int)hms % 100;
gpst.Minute = (((int)hms - gpst.Second) / 100) % 100;
gpst.Hour = (int)hms / 10000;
#endif //PIOS_GPS_PURISTIC
// get latitude decimal degrees
GpsData->Latitude = NMEA_real_to_float(param[2])*1e7;
if (param[3][0] == 'S')
GpsData->Latitude = -GpsData->Latitude;
// get longitude decimal degrees
GpsData->Longitude = NMEA_real_to_float(param[4])*1e7;
if (param[5][0] == 'W')
GpsData->Longitude = -GpsData->Longitude;
// get number of satellites used in GPS solution
GpsData->Satellites = atoi(param[7]);
// next field: HDOP
GpsData->HDOP = NMEA_real_to_float(param[8]);
// get altitude (in meters mm.m)
GpsData->Altitude = NMEA_real_to_float(param[9]);
// next field: geoid separation
GpsData->GeoidSeparation = NMEA_real_to_float(param[10]);
// Mode: 1=Fix not available, 2=2D, 3=3D
switch (atoi(param[11])) {
case 1:
GpsData->Status = GPSPOSITION_STATUS_NOFIX;
break;
case 2:
GpsData->Status = GPSPOSITION_STATUS_FIX2D;
break;
case 3:
GpsData->Status = GPSPOSITION_STATUS_FIX3D;
break;
default:
/* Unhandled */
return false;
break;
}
// get course over ground in degrees [ddd.dd]
GpsData->Heading = NMEA_real_to_float(param[12]);
// get speed in km/h
GpsData->Groundspeed = NMEA_real_to_float(param[13]);
// to m/s
GpsData->Groundspeed /= 3.6;
#if !defined(PIOS_GPS_PURISTIC)
gpst.Day = atoi(param[14]);
gpst.Month = atoi(param[15]);
gpst.Year = atoi(param[16]);
GPSTimeSet(&gpst);
#endif //PIOS_GPS_PURISTIC
return true;
}
#endif // #if defined(ENABLE_GPS_NMEA) || defined(ENABLE_GPS_ONESENTENCE_GTOP)

View File

@ -34,8 +34,6 @@
#ifndef GPS_H #ifndef GPS_H
#define GPS_H #define GPS_H
#include "gps_mode.h"
int32_t GPSInitialize(void); int32_t GPSInitialize(void);
#endif // GPS_H #endif // GPS_H

View File

@ -33,11 +33,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "gps_mode.h"
#if defined(ENABLE_GPS_NMEA) || defined(ENABLE_GPS_ONESENTENCE_GTOP) extern bool NMEA_update_position(char *nmea_sentence);
extern bool NMEA_update_position(char *nmea_sentence); extern bool NMEA_checksum(char *nmea_sentence);
extern bool NMEA_checksum(char *nmea_sentence);
#endif
#endif /* NMEA_H */ #endif /* NMEA_H */

View File

@ -1,58 +0,0 @@
/**
******************************************************************************
* @addtogroup OpenPilotModules OpenPilot Modules
* @{
* @addtogroup GSPModule GPS Module
* @brief Process GPS information
* @{
*
* @file gps_mode.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Include file of the GPS module.
* As with all modules only the initialize function is exposed all other
* interactions with the module take place through the event queue and
* objects.
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef GPS_MODE_H
#define GPS_MODE_H
// ****************
// you MUST have one of these uncommented - and ONLY one
//#define ENABLE_GPS_BINARY_GTOP // uncomment this if we are using GTOP BINARY mode
//#define ENABLE_GPS_ONESENTENCE_GTOP // uncomment this if we are using GTOP SINGLE SENTENCE mode
#define ENABLE_GPS_NMEA // uncomment this if we are using NMEA mode
// ****************
// make sure they have defined a protocol to use
#if !defined(ENABLE_GPS_BINARY_GTOP) && !defined(ENABLE_GPS_ONESENTENCE_GTOP) && !defined(ENABLE_GPS_NMEA)
#error YOU MUST SELECT THE DESIRED GPS PROTOCOL IN gps_mode.h!
#endif
// ****************
#endif
/**
* @}
* @}
*/

View File

@ -251,6 +251,11 @@ static void objectUpdatedCb(UAVObjEvent * ev)
|| objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLOBJECTS) { || objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLOBJECTS) {
retval = UAVObjDeleteMetaobjects(); retval = UAVObjDeleteMetaobjects();
} }
} else if (objper.Operation == OBJECTPERSISTENCE_OPERATION_FULLERASE) {
retval = -1;
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
retval = PIOS_FLASHFS_Format();
#endif
} }
if(retval == 0) { if(retval == 0) {
objper.Operation = OBJECTPERSISTENCE_OPERATION_COMPLETED; objper.Operation = OBJECTPERSISTENCE_OPERATION_COMPLETED;

View File

@ -526,7 +526,6 @@ static const struct pios_spektrum_cfg pios_spektrum_cfg = {
#define PIOS_COM_TELEM_RF_TX_BUF_LEN 192 #define PIOS_COM_TELEM_RF_TX_BUF_LEN 192
#define PIOS_COM_GPS_RX_BUF_LEN 96 #define PIOS_COM_GPS_RX_BUF_LEN 96
#define PIOS_COM_GPS_TX_BUF_LEN 96
#define PIOS_COM_TELEM_USB_RX_BUF_LEN 192 #define PIOS_COM_TELEM_USB_RX_BUF_LEN 192
#define PIOS_COM_TELEM_USB_TX_BUF_LEN 192 #define PIOS_COM_TELEM_USB_TX_BUF_LEN 192
@ -1079,12 +1078,10 @@ void PIOS_Board_Init(void) {
PIOS_Assert(0); PIOS_Assert(0);
} }
uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_GPS_RX_BUF_LEN); uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_GPS_RX_BUF_LEN);
uint8_t * tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_GPS_TX_BUF_LEN);
PIOS_Assert(rx_buffer); PIOS_Assert(rx_buffer);
PIOS_Assert(tx_buffer);
if (PIOS_COM_Init(&pios_com_gps_id, &pios_usart_com_driver, pios_usart_gps_id, if (PIOS_COM_Init(&pios_com_gps_id, &pios_usart_com_driver, pios_usart_gps_id,
rx_buffer, PIOS_COM_GPS_RX_BUF_LEN, rx_buffer, PIOS_COM_GPS_RX_BUF_LEN,
tx_buffer, PIOS_COM_GPS_TX_BUF_LEN)) { NULL, 0)) {
PIOS_Assert(0); PIOS_Assert(0);
} }
} }
@ -1097,6 +1094,7 @@ void PIOS_Board_Init(void) {
/* Configure the selected receiver */ /* Configure the selected receiver */
uint8_t manualcontrolsettings_inputmode; uint8_t manualcontrolsettings_inputmode;
ManualControlSettingsInitialize();
ManualControlSettingsInputModeGet(&manualcontrolsettings_inputmode); ManualControlSettingsInputModeGet(&manualcontrolsettings_inputmode);
switch (manualcontrolsettings_inputmode) { switch (manualcontrolsettings_inputmode) {

View File

@ -72,7 +72,7 @@ const struct pios_udp_cfg pios_udp_aux_cfg = {
#define PIOS_COM_TELEM_RF_RX_BUF_LEN 192 #define PIOS_COM_TELEM_RF_RX_BUF_LEN 192
#define PIOS_COM_TELEM_RF_TX_BUF_LEN 192 #define PIOS_COM_TELEM_RF_TX_BUF_LEN 192
#define PIOS_COM_GPS_RX_BUF_LEN 192 #define PIOS_COM_GPS_RX_BUF_LEN 96
/* /*
* Board specific number of devices. * Board specific number of devices.
@ -165,12 +165,10 @@ void PIOS_Board_Init(void) {
PIOS_Assert(0); PIOS_Assert(0);
} }
uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_GPS_RX_BUF_LEN); uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_GPS_RX_BUF_LEN);
uint8_t * tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_GPS_RX_BUF_LEN);
PIOS_Assert(rx_buffer); PIOS_Assert(rx_buffer);
PIOS_Assert(tx_buffer);
if (PIOS_COM_Init(&pios_com_gps_id, &pios_udp_com_driver, pios_udp_gps_id, if (PIOS_COM_Init(&pios_com_gps_id, &pios_udp_com_driver, pios_udp_gps_id,
rx_buffer, PIOS_COM_GPS_RX_BUF_LEN, rx_buffer, PIOS_COM_GPS_RX_BUF_LEN,
tx_buffer, PIOS_COM_GPS_RX_BUF_LEN)) { NULL, 0)) {
PIOS_Assert(0); PIOS_Assert(0);
} }
} }

View File

@ -116,6 +116,19 @@ int32_t PIOS_FLASHFS_Init()
return 0; return 0;
} }
/**
* @brief Erase the whole flash chip and create the file system
* @return 0 if successful, -1 if not
*/
int32_t PIOS_FLASHFS_Format()
{
if(PIOS_Flash_W25X_EraseChip() != 0)
return -1;
if(PIOS_FLASHFS_ClearObjectTableHeader() != 0)
return -1;
return 0;
}
/** /**
* @brief Erase the headers for all objects in the flash chip * @brief Erase the headers for all objects in the flash chip
* @return 0 if successful, -1 if not * @return 0 if successful, -1 if not

View File

@ -8,7 +8,6 @@
* *
* @file pios_spektrum.c * @file pios_spektrum.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* Parts by Thorsten Klose (tk@midibox.org) (tk@midibox.org)
* @brief USART commands. Inits USARTs, controls USARTs & Interrupt handlers. (STM32 dependent) * @brief USART commands. Inits USARTs, controls USARTs & Interrupt handlers. (STM32 dependent)
* @see The GNU Public License (GPL) Version 3 * @see The GNU Public License (GPL) Version 3
* *
@ -59,7 +58,7 @@ uint8_t sync_of = 0;
uint16_t supv_timer=0; uint16_t supv_timer=0;
static void PIOS_SPEKTRUM_Supervisor(uint32_t spektrum_id); static void PIOS_SPEKTRUM_Supervisor(uint32_t spektrum_id);
static bool PIOS_SPEKTRUM_Bind(const struct pios_spektrum_cfg * cfg); static bool PIOS_SPEKTRUM_Bind(const struct pios_spektrum_cfg * cfg, uint8_t bind);
static int32_t PIOS_SPEKTRUM_Decode(uint8_t b); static int32_t PIOS_SPEKTRUM_Decode(uint8_t b);
static uint16_t PIOS_SPEKTRUM_RxInCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield) static uint16_t PIOS_SPEKTRUM_RxInCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield)
@ -85,11 +84,11 @@ static uint16_t PIOS_SPEKTRUM_RxInCallback(uint32_t context, uint8_t * buf, uint
/** /**
* Bind and Initialise Spektrum satellite receiver * Bind and Initialise Spektrum satellite receiver
*/ */
int32_t PIOS_SPEKTRUM_Init(uint32_t * spektrum_id, const struct pios_spektrum_cfg *cfg, const struct pios_com_driver * driver, uint32_t lower_id, bool bind) int32_t PIOS_SPEKTRUM_Init(uint32_t * spektrum_id, const struct pios_spektrum_cfg *cfg, const struct pios_com_driver * driver, uint32_t lower_id, uint8_t bind)
{ {
// TODO: need setting flag for bind on next powerup // TODO: need setting flag for bind on next powerup
if (bind) { if (bind) {
PIOS_SPEKTRUM_Bind(cfg); PIOS_SPEKTRUM_Bind(cfg,bind);
} }
(driver->bind_rx_cb)(lower_id, PIOS_SPEKTRUM_RxInCallback, 0); (driver->bind_rx_cb)(lower_id, PIOS_SPEKTRUM_RxInCallback, 0);
@ -121,9 +120,15 @@ static int32_t PIOS_SPEKTRUM_Get(uint32_t rcvr_id, uint8_t channel)
* \output true Successful bind * \output true Successful bind
* \output false Bind failed * \output false Bind failed
*/ */
static bool PIOS_SPEKTRUM_Bind(const struct pios_spektrum_cfg * cfg) static bool PIOS_SPEKTRUM_Bind(const struct pios_spektrum_cfg * cfg, uint8_t bind)
{ {
#define BIND_PULSES 5 GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = cfg->bind.init.GPIO_Pin;
GPIO_InitStructure.GPIO_Speed = cfg->bind.init.GPIO_Speed;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
/* just to limit bind pulses */
bind=(bind<=10)?bind:10;
GPIO_Init(cfg->bind.gpio, &cfg->bind.init); GPIO_Init(cfg->bind.gpio, &cfg->bind.init);
/* RX line, set high */ /* RX line, set high */
@ -132,7 +137,7 @@ static bool PIOS_SPEKTRUM_Bind(const struct pios_spektrum_cfg * cfg)
/* on CC works upto 140ms, I guess bind window is around 20-140ms after powerup */ /* on CC works upto 140ms, I guess bind window is around 20-140ms after powerup */
PIOS_DELAY_WaitmS(60); PIOS_DELAY_WaitmS(60);
for (int i = 0; i < BIND_PULSES ; i++) { for (int i = 0; i < bind ; i++) {
/* RX line, drive low for 120us */ /* RX line, drive low for 120us */
GPIO_ResetBits(cfg->bind.gpio, cfg->bind.init.GPIO_Pin); GPIO_ResetBits(cfg->bind.gpio, cfg->bind.init.GPIO_Pin);
PIOS_DELAY_WaituS(120); PIOS_DELAY_WaituS(120);
@ -141,6 +146,7 @@ static bool PIOS_SPEKTRUM_Bind(const struct pios_spektrum_cfg * cfg)
PIOS_DELAY_WaituS(120); PIOS_DELAY_WaituS(120);
} }
/* RX line, set input and wait for data, PIOS_SPEKTRUM_Init */ /* RX line, set input and wait for data, PIOS_SPEKTRUM_Init */
GPIO_Init(cfg->bind.gpio, &GPIO_InitStructure);
return true; return true;
} }
@ -172,9 +178,10 @@ static int32_t PIOS_SPEKTRUM_Decode(uint8_t b)
CaptureValue[7]=b; CaptureValue[7]=b;
} }
#endif #endif
/* Known sync bytes, 0x01, 0x02, 0x12 */ /* Known sync bytes, 0x01, 0x02, 0x12, 0xb2 */
/* 0xb2 DX8 3bind pulses only */
if (bytecount == 2) { if (bytecount == 2) {
if (b == 0x01) { if ((b == 0x01) || (b == 0xb2)) {
datalength=0; // 10bit datalength=0; // 10bit
//frames=1; //frames=1;
sync = 1; sync = 1;
@ -234,17 +241,17 @@ static int32_t PIOS_SPEKTRUM_Decode(uint8_t b)
*@brief clears the channel values *@brief clears the channel values
*/ */
static void PIOS_SPEKTRUM_Supervisor(uint32_t spektrum_id) { static void PIOS_SPEKTRUM_Supervisor(uint32_t spektrum_id) {
/* 125hz */ /* 625hz */
supv_timer++; supv_timer++;
if(supv_timer > 5) { if(supv_timer > 4) {
/* sync between frames */ /* sync between frames */
sync = 0; sync = 0;
bytecount = 0; bytecount = 0;
prev_byte = 0xFF; prev_byte = 0xFF;
frame_error = 0; frame_error = 0;
sync_of++; sync_of++;
/* watchdog activated after 100ms silence */ /* watchdog activated after 200ms silence */
if (sync_of > 12) { if (sync_of > 30) {
/* signal lost */ /* signal lost */
sync_of = 0; sync_of = 0;
for (int i = 0; i < PIOS_SPEKTRUM_NUM_INPUTS; i++) { for (int i = 0; i < PIOS_SPEKTRUM_NUM_INPUTS; i++) {

View File

@ -32,6 +32,7 @@
#include "uavobjectmanager.h" #include "uavobjectmanager.h"
int32_t PIOS_FLASHFS_Init(); int32_t PIOS_FLASHFS_Init();
int32_t PIOS_FLASHFS_Format();
int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data); 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_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data);
int32_t PIOS_FLASHFS_ObjDelete(UAVObjHandle obj, uint16_t instId); int32_t PIOS_FLASHFS_ObjDelete(UAVObjHandle obj, uint16_t instId);

View File

@ -42,7 +42,7 @@ struct pios_spektrum_cfg {
extern const struct pios_rcvr_driver pios_spektrum_rcvr_driver; extern const struct pios_rcvr_driver pios_spektrum_rcvr_driver;
extern int32_t PIOS_SPEKTRUM_Init(uint32_t * spektrum_id, const struct pios_spektrum_cfg *cfg, const struct pios_com_driver * driver, uint32_t lower_id, bool bind); extern int32_t PIOS_SPEKTRUM_Init(uint32_t * spektrum_id, const struct pios_spektrum_cfg *cfg, const struct pios_com_driver * driver, uint32_t lower_id, uint8_t bind);
#endif /* PIOS_PWM_PRIV_H */ #endif /* PIOS_PWM_PRIV_H */

View File

@ -51,7 +51,7 @@ typedef struct {
typedef uint8_t uavtalk_checksum; typedef uint8_t uavtalk_checksum;
#define UAVTALK_CHECKSUM_LENGTH sizeof(uavtalk_checksum) #define UAVTALK_CHECKSUM_LENGTH sizeof(uavtalk_checksum)
#define UAVTALK_MAX_PAYLOAD_LENGTH UAVOBJECTS_LARGEST #define UAVTALK_MAX_PAYLOAD_LENGTH (UAVOBJECTS_LARGEST + 1)
#define UAVTALK_MIN_PACKET_LENGTH UAVTALK_MAX_HEADER_LENGTH + UAVTALK_CHECKSUM_LENGTH #define UAVTALK_MIN_PACKET_LENGTH UAVTALK_MAX_HEADER_LENGTH + UAVTALK_CHECKSUM_LENGTH
#define UAVTALK_MAX_PACKET_LENGTH UAVTALK_MIN_PACKET_LENGTH + UAVTALK_MAX_PAYLOAD_LENGTH #define UAVTALK_MAX_PACKET_LENGTH UAVTALK_MIN_PACKET_LENGTH + UAVTALK_MAX_PAYLOAD_LENGTH

View File

@ -0,0 +1,159 @@
/**
******************************************************************************
*
* @file cachedsvgitem.h
* @author Dmytro Poplavskiy Copyright (C) 2011.
* @{
* @brief OpenGL texture cached SVG item
*****************************************************************************/
/*
* 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 "cachedsvgitem.h"
#include <QGLContext>
#include <QDebug>
#ifndef GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE 0x812F
#endif
CachedSvgItem::CachedSvgItem(QGraphicsItem * parent) :
QGraphicsSvgItem(parent),
m_context(0),
m_texture(0),
m_scale(1.0)
{
setCacheMode(NoCache);
}
CachedSvgItem::CachedSvgItem(const QString & fileName, QGraphicsItem * parent):
QGraphicsSvgItem(fileName, parent),
m_context(0),
m_texture(0),
m_scale(1.0)
{
setCacheMode(NoCache);
}
CachedSvgItem::~CachedSvgItem()
{
if (m_context && m_texture) {
m_context->makeCurrent();
glDeleteTextures(1, &m_texture);
}
}
void CachedSvgItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
if (painter->paintEngine()->type() != QPaintEngine::OpenGL &&
painter->paintEngine()->type() != QPaintEngine::OpenGL2) {
//Fallback to direct painting
QGraphicsSvgItem::paint(painter, option, widget);
return;
}
QRectF br = boundingRect();
QTransform transform = painter->worldTransform();
qreal sceneScale = transform.map(QLineF(0,0,1,0)).length();
bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST);
bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
painter->beginNativePainting();
if (stencilTestEnabled)
glEnable(GL_STENCIL_TEST);
if (scissorTestEnabled)
glEnable(GL_SCISSOR_TEST);
bool dirty = false;
if (!m_texture) {
glGenTextures(1, &m_texture);
m_context = const_cast<QGLContext*>(QGLContext::currentContext());
dirty = true;
}
if (!qFuzzyCompare(sceneScale, m_scale)) {
m_scale = sceneScale;
dirty = true;
}
int textureWidth = (int(br.width()*m_scale) + 3) & ~3;
int textureHeight = (int(br.height()*m_scale) + 3) & ~3;
if (dirty) {
//qDebug() << "re-render image";
QImage img(textureWidth, textureHeight, QImage::Format_ARGB32);
{
img.fill(Qt::transparent);
QPainter p;
p.begin(&img);
p.setRenderHints(painter->renderHints());
p.translate(br.topLeft());
p.scale(m_scale, m_scale);
QGraphicsSvgItem::paint(&p, option, 0);
p.end();
img = img.rgbSwapped();
}
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_texture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA,
textureWidth,
textureHeight,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
img.bits());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glDisable(GL_TEXTURE_2D);
dirty = false;
}
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_texture);
//texture may be slightly large than svn image, ensure only used area is rendered
qreal tw = br.width()*m_scale/textureWidth;
qreal th = br.height()*m_scale/textureHeight;
glBegin(GL_QUADS);
glTexCoord2d(0, 0 ); glVertex3d(br.left(), br.top(), -1);
glTexCoord2d(tw, 0 ); glVertex3d(br.right(), br.top(), -1);
glTexCoord2d(tw, th); glVertex3d(br.right(), br.bottom(), -1);
glTexCoord2d(0, th); glVertex3d(br.left(), br.bottom(), -1);
glEnd();
glDisable(GL_TEXTURE_2D);
painter->endNativePainting();
}

View File

@ -1,16 +1,10 @@
/** /**
****************************************************************************** ******************************************************************************
* @addtogroup OpenPilotModules OpenPilot Modules
* @{
* @addtogroup GSPModule GPS Module
* @brief Process GPS information
* @{
*
* @file GTOP_BIN.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief GPS module, handles GPS and NMEA stream
* @see The GNU Public License (GPL) Version 3
* *
* @file cachedsvgitem.h
* @author Dmytro Poplavskiy Copyright (C) 2011.
* @{
* @brief OpenGL texture cached SVG item
*****************************************************************************/ *****************************************************************************/
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -28,15 +22,33 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifndef GTOP_BIN_H #ifndef CACHEDSVGITEM_H
#define GTOP_BIN_H #define CACHEDSVGITEM_H
#include <stdint.h> #include <QGraphicsSvgItem>
#include "gps_mode.h" #include <QGLContext>
#ifdef ENABLE_GPS_BINARY_GTOP #include "utils_global.h"
extern int GTOP_BIN_update_position(uint8_t b, volatile uint32_t *chksum_errors, volatile uint32_t *parsing_errors);
extern void GTOP_BIN_init(void); class QGLContext;
#endif
//Cache Svg item as GL Texture.
//Texture is regenerated each time item is scaled
//but it's reused during rotation, unlike DeviceCoordinateCache mode
class QTCREATOR_UTILS_EXPORT CachedSvgItem: public QGraphicsSvgItem
{
Q_OBJECT
public:
CachedSvgItem(QGraphicsItem * parent = 0);
CachedSvgItem(const QString & fileName, QGraphicsItem * parent = 0);
~CachedSvgItem();
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
private:
QGLContext *m_context;
GLuint m_texture;
qreal m_scale;
};
#endif #endif

View File

@ -3,7 +3,9 @@ TARGET = Utils
QT += gui \ QT += gui \
network \ network \
xml xml \
svg \
opengl
DEFINES += QTCREATOR_UTILS_LIB DEFINES += QTCREATOR_UTILS_LIB
@ -48,7 +50,8 @@ SOURCES += reloadpromptutils.cpp \
homelocationutil.cpp \ homelocationutil.cpp \
mytabbedstackwidget.cpp \ mytabbedstackwidget.cpp \
mytabwidget.cpp \ mytabwidget.cpp \
mylistwidget.cpp mylistwidget.cpp \
cachedsvgitem.cpp
SOURCES += xmlconfig.cpp SOURCES += xmlconfig.cpp
win32 { win32 {
@ -102,7 +105,8 @@ HEADERS += utils_global.h \
homelocationutil.h \ homelocationutil.h \
mytabbedstackwidget.h \ mytabbedstackwidget.h \
mytabwidget.h \ mytabwidget.h \
mylistwidget.h mylistwidget.h \
cachedsvgitem.h
HEADERS += xmlconfig.h HEADERS += xmlconfig.h
FORMS += filewizardpage.ui \ FORMS += filewizardpage.ui \

View File

@ -30,7 +30,7 @@
#include <QStringList> #include <QStringList>
#include <QTimer> #include <QTimer>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include "objectpersistence.h"
ConfigPlugin::ConfigPlugin() ConfigPlugin::ConfigPlugin()
{ {
@ -58,7 +58,7 @@ bool ConfigPlugin::initialize(const QStringList& args, QString *errMsg)
"ConfigPlugin.EraseAll", "ConfigPlugin.EraseAll",
QList<int>() << QList<int>() <<
Core::Constants::C_GLOBAL_ID); Core::Constants::C_GLOBAL_ID);
cmd->action()->setText("Erase all settings from board..."); cmd->action()->setText(tr("Erase all settings from board..."));
ac->menu()->addSeparator(); ac->menu()->addSeparator();
ac->appendGroup("Utilities"); ac->appendGroup("Utilities");
@ -80,6 +80,17 @@ bool ConfigPlugin::initialize(const QStringList& args, QString *errMsg)
return true; return true;
} }
/**
* @brief Return handle to object manager
*/
UAVObjectManager * ConfigPlugin::getObjectManager()
{
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager * objMngr = pm->getObject<UAVObjectManager>();
Q_ASSERT(objMngr);
return objMngr;
}
void ConfigPlugin::extensionsInitialized() void ConfigPlugin::extensionsInitialized()
{ {
cmd->action()->setEnabled(false); cmd->action()->setEnabled(false);
@ -122,18 +133,19 @@ void ConfigPlugin::eraseAllSettings()
return; return;
settingsErased = false; settingsErased = false;
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ObjectPersistence* objper = ObjectPersistence::GetInstance(getObjectManager());
UAVObjectManager * objMngr = pm->getObject<UAVObjectManager>();
Q_ASSERT(objMngr);
ObjectPersistence* objper = dynamic_cast<ObjectPersistence*>( objMngr->getObject(ObjectPersistence::NAME) );
Q_ASSERT(objper); Q_ASSERT(objper);
connect(objper, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(eraseDone(UAVObject *))); connect(objper, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(eraseDone(UAVObject *)));
ObjectPersistence::DataFields data;
data.Operation = ObjectPersistence::OPERATION_DELETE; ObjectPersistence::DataFields data = objper->getData();
data.Selection = ObjectPersistence::SELECTION_ALLSETTINGS; data.Operation = ObjectPersistence::OPERATION_FULLERASE;
// No need for manual updated event, this is triggered by setData
// based on UAVO meta data
objper->setData(data); objper->setData(data);
objper->updated(); objper->updated();
QTimer::singleShot(1500,this,SLOT(eraseFailed())); QTimer::singleShot(6000,this,SLOT(eraseFailed()));
} }
@ -141,37 +153,47 @@ void ConfigPlugin::eraseFailed()
{ {
if (settingsErased) if (settingsErased)
return; return;
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager * objMngr = pm->getObject<UAVObjectManager>(); ObjectPersistence* objper = ObjectPersistence::GetInstance(getObjectManager());
Q_ASSERT(objMngr);
ObjectPersistence* objper = dynamic_cast<ObjectPersistence*>( objMngr->getObject(ObjectPersistence::NAME)); ObjectPersistence::DataFields data = objper->getData();
disconnect(objper, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(eraseDone(UAVObject *))); if(data.Operation == ObjectPersistence::OPERATION_FULLERASE) {
QMessageBox msgBox; // First attempt via flash erase failed. Fall back on erase all settings
msgBox.setText(tr("Error trying to erase settings.")); data.Operation = ObjectPersistence::OPERATION_DELETE;
msgBox.setInformativeText(tr("Power-cycle your board. Settings might be inconsistent.")); data.Selection = ObjectPersistence::SELECTION_ALLSETTINGS;
msgBox.setStandardButtons(QMessageBox::Ok); objper->setData(data);
msgBox.setDefaultButton(QMessageBox::Ok); objper->updated();
msgBox.exec(); QTimer::singleShot(1500,this,SLOT(eraseFailed()));
} else {
disconnect(objper, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(eraseDone(UAVObject *)));
QMessageBox msgBox;
msgBox.setText(tr("Error trying to erase settings."));
msgBox.setInformativeText(tr("Power-cycle your board after removing all blades. Settings might be inconsistent."));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
} }
void ConfigPlugin::eraseDone(UAVObject * obj) void ConfigPlugin::eraseDone(UAVObject * obj)
{ {
QMessageBox msgBox; QMessageBox msgBox;
ObjectPersistence* objper = dynamic_cast<ObjectPersistence*>(sender()); ObjectPersistence* objper = ObjectPersistence::GetInstance(getObjectManager());
Q_ASSERT(obj->getName().compare("ObjectPersistence") == 0); ObjectPersistence::DataFields data = objper->getData();
QString tmp = obj->getField("Operation")->getValue().toString(); Q_ASSERT(obj->getInstID() == objper->getInstID());
if (obj->getField("Operation")->getValue().toString().compare(QString("Delete")) == 0 ) {
if(data.Operation != ObjectPersistence::OPERATION_COMPLETED) {
return; return;
} }
disconnect(objper, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(eraseDone(UAVObject *))); disconnect(objper, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(eraseDone(UAVObject *)));
if (obj->getField("Operation")->getValue().toString().compare(QString("Completed")) == 0) { if (data.Operation == ObjectPersistence::OPERATION_COMPLETED) {
settingsErased = true; settingsErased = true;
msgBox.setText(tr("Settings are now erased.")); msgBox.setText(tr("Settings are now erased."));
msgBox.setInformativeText(tr("Please now power-cycle your board to complete reset.")); msgBox.setInformativeText(tr("Please now power-cycle your board to complete reset."));
} else { } else {
msgBox.setText(tr("Error trying to erase settings.")); msgBox.setText(tr("Error trying to erase settings."));
msgBox.setInformativeText(tr("Power-cycle your board. Settings might be inconsistent.")); msgBox.setInformativeText(tr("Power-cycle your board after removing all blades. Settings might be inconsistent."));
} }
msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok);

View File

@ -48,6 +48,7 @@ public:
ConfigPlugin(); ConfigPlugin();
~ConfigPlugin(); ~ConfigPlugin();
UAVObjectManager * getObjectManager();
void extensionsInitialized(); void extensionsInitialized();
bool initialize(const QStringList & arguments, QString * errorString); bool initialize(const QStringList & arguments, QString * errorString);
void shutdown(); void shutdown();

View File

@ -6,649 +6,689 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>639</width> <width>683</width>
<height>611</height> <height>685</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<widget class="QGroupBox" name="groupBox"> <widget class="QScrollArea" name="scrollArea">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>1</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <property name="frameShape">
<size> <enum>QFrame::NoFrame</enum>
<width>0</width>
<height>150</height>
</size>
</property> </property>
<property name="title"> <property name="widgetResizable">
<string>Rate Stabilization Coefficients (Inner Loop)</string> <bool>true</bool>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <widget class="QWidget" name="scrollAreaWidgetContents">
<item row="0" column="2"> <property name="geometry">
<widget class="QLabel" name="label_12"> <rect>
<property name="text"> <x>0</x>
<string>Kp</string> <y>0</y>
</property> <width>665</width>
<property name="alignment"> <height>627</height>
<set>Qt::AlignCenter</set> </rect>
</property> </property>
</widget> <property name="sizePolicy">
</item> <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<item row="0" column="3"> <horstretch>0</horstretch>
<widget class="QLabel" name="label_13"> <verstretch>0</verstretch>
<property name="text"> </sizepolicy>
<string>Ki</string> </property>
</property> <layout class="QVBoxLayout" name="verticalLayout">
<property name="alignment"> <property name="spacing">
<set>Qt::AlignCenter</set> <number>0</number>
</property> </property>
</widget> <property name="margin">
</item> <number>0</number>
<item row="0" column="4"> </property>
<widget class="QLabel" name="label_14"> <item>
<property name="text"> <widget class="QGroupBox" name="groupBox">
<string>ILimit</string> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<property name="alignment"> <horstretch>0</horstretch>
<set>Qt::AlignCenter</set> <verstretch>0</verstretch>
</property> </sizepolicy>
</widget> </property>
</item> <property name="minimumSize">
<item row="1" column="1"> <size>
<widget class="QLabel" name="label_10"> <width>0</width>
<property name="text"> <height>150</height>
<string>Roll</string> </size>
</property> </property>
</widget> <property name="title">
</item> <string>Rate Stabilization Coefficients (Inner Loop)</string>
<item row="1" column="2"> </property>
<widget class="QDoubleSpinBox" name="rateRollKp"> <layout class="QGridLayout" name="gridLayout_3">
<property name="toolTip"> <item row="0" column="2">
<string>Slowly raise Kp until you start seeing clear oscillations when you fly. <widget class="QLabel" name="label_12">
<property name="text">
<string>Kp</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Ki</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="label_14">
<property name="text">
<string>ILimit</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Roll</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QDoubleSpinBox" name="rateRollKp">
<property name="toolTip">
<string>Slowly raise Kp until you start seeing clear oscillations when you fly.
Then lower the value by 20% or so.</string> Then lower the value by 20% or so.</string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.000100000000000</double> <double>0.000100000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="3"> <item row="1" column="3">
<widget class="QDoubleSpinBox" name="rateRollKi"> <widget class="QDoubleSpinBox" name="rateRollKi">
<property name="toolTip"> <property name="toolTip">
<string>I factor for rate stabilization is usually very low or even zero.</string> <string>I factor for rate stabilization is usually very low or even zero.</string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.000100000000000</double> <double>0.000100000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="4"> <item row="1" column="4">
<widget class="QDoubleSpinBox" name="rateRollILimit"> <widget class="QDoubleSpinBox" name="rateRollILimit">
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.000100000000000</double> <double>0.000100000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QCheckBox" name="linkRateRP"> <widget class="QCheckBox" name="linkRateRP">
<property name="toolTip"> <property name="toolTip">
<string>If checked, the Roll and Pitch factors will be identical. <string>If checked, the Roll and Pitch factors will be identical.
When you change one, the other is updated.</string> When you change one, the other is updated.</string>
</property> </property>
<property name="text"> <property name="text">
<string>Link</string> <string>Link</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QLabel" name="label_11"> <widget class="QLabel" name="label_11">
<property name="text"> <property name="text">
<string>Pitch</string> <string>Pitch</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="2"> <item row="2" column="2">
<widget class="QDoubleSpinBox" name="ratePitchKp"> <widget class="QDoubleSpinBox" name="ratePitchKp">
<property name="toolTip"> <property name="toolTip">
<string>Slowly raise Kp until you start seeing clear oscillations when you fly. <string>Slowly raise Kp until you start seeing clear oscillations when you fly.
Then lower the value by 20% or so.</string> Then lower the value by 20% or so.</string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.000100000000000</double> <double>0.000100000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="3"> <item row="2" column="3">
<widget class="QDoubleSpinBox" name="ratePitchKi"> <widget class="QDoubleSpinBox" name="ratePitchKi">
<property name="toolTip"> <property name="toolTip">
<string>I factor for rate stabilization is usually very low or even zero.</string> <string>I factor for rate stabilization is usually very low or even zero.</string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.000100000000000</double> <double>0.000100000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="4"> <item row="2" column="4">
<widget class="QDoubleSpinBox" name="ratePitchILimit"> <widget class="QDoubleSpinBox" name="ratePitchILimit">
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.000100000000000</double> <double>0.000100000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
<widget class="QLabel" name="label_15"> <widget class="QLabel" name="label_15">
<property name="text"> <property name="text">
<string>Yaw</string> <string>Yaw</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2"> <item row="3" column="2">
<widget class="QDoubleSpinBox" name="rateYawKp"> <widget class="QDoubleSpinBox" name="rateYawKp">
<property name="toolTip"> <property name="toolTip">
<string>Slowly raise Kp until you start seeing clear oscillations when you fly. <string>Slowly raise Kp until you start seeing clear oscillations when you fly.
Then lower the value by 20% or so. Then lower the value by 20% or so.
You can usually go for higher values for Yaw factors.</string> You can usually go for higher values for Yaw factors.</string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.000100000000000</double> <double>0.000100000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="3"> <item row="3" column="3">
<widget class="QDoubleSpinBox" name="rateYawKi"> <widget class="QDoubleSpinBox" name="rateYawKi">
<property name="toolTip"> <property name="toolTip">
<string>As a rule of thumb, you can set YawRate Ki at roughly the same <string>As a rule of thumb, you can set YawRate Ki at roughly the same
value as YawRate Kp.</string> value as YawRate Kp.</string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.000100000000000</double> <double>0.000100000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="4"> <item row="3" column="4">
<widget class="QDoubleSpinBox" name="rateYawILimit"> <widget class="QDoubleSpinBox" name="rateYawILimit">
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.000100000000000</double> <double>0.000100000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="verticalSpacer_3"> <spacer name="verticalSpacer_3">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeType"> <property name="sizeType">
<enum>QSizePolicy::Fixed</enum> <enum>QSizePolicy::Fixed</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>5</height> <height>13</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding"> <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>0</width>
<height>150</height> <height>150</height>
</size> </size>
</property> </property>
<property name="title"> <property name="title">
<string>Attitude Stabization Coefficients (Outer Loop)</string> <string>Attitude Stabization Coefficients (Outer Loop)</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="2"> <item row="3" column="2">
<widget class="QDoubleSpinBox" name="rollKp"> <widget class="QDoubleSpinBox" name="rollKp">
<property name="toolTip"> <property name="toolTip">
<string>Once Rate stabilization is done, you should increase the Kp factor until the airframe oscillates again, and go back down 20% or so. <string>Once Rate stabilization is done, you should increase the Kp factor until the airframe oscillates again, and go back down 20% or so.
</string> </string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.100000000000000</double> <double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="3"> <item row="3" column="3">
<widget class="QDoubleSpinBox" name="rollKi"> <widget class="QDoubleSpinBox" name="rollKi">
<property name="toolTip"> <property name="toolTip">
<string>Ki can usually be almost identical to Kp.</string> <string>Ki can usually be almost identical to Kp.</string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.100000000000000</double> <double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="4"> <item row="3" column="4">
<widget class="QDoubleSpinBox" name="rollILimit"> <widget class="QDoubleSpinBox" name="rollILimit">
<property name="toolTip"> <property name="toolTip">
<string>ILimit can be equal to three to four times Ki, but you can adjust <string>ILimit can be equal to three to four times Ki, but you can adjust
depending on whether your airframe is well balanced, and your depending on whether your airframe is well balanced, and your
flying style.</string> flying style.</string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.100000000000000</double> <double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="2"> <item row="2" column="2">
<widget class="QLabel" name="label_19"> <widget class="QLabel" name="label_19">
<property name="text"> <property name="text">
<string>Kp</string> <string>Kp</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignCenter</set> <set>Qt::AlignCenter</set>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="3"> <item row="2" column="3">
<widget class="QLabel" name="label_20"> <widget class="QLabel" name="label_20">
<property name="text"> <property name="text">
<string>Ki</string> <string>Ki</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignCenter</set> <set>Qt::AlignCenter</set>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="4"> <item row="2" column="4">
<widget class="QLabel" name="label_21"> <widget class="QLabel" name="label_21">
<property name="text"> <property name="text">
<string>ILimit</string> <string>ILimit</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignCenter</set> <set>Qt::AlignCenter</set>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="4"> <item row="7" column="4">
<widget class="QDoubleSpinBox" name="yawILimit"> <widget class="QDoubleSpinBox" name="yawILimit">
<property name="toolTip"> <property name="toolTip">
<string>ILimit can be equal to three to four times Ki, but you can adjust <string>ILimit can be equal to three to four times Ki, but you can adjust
depending on whether your airframe is well balanced, and your depending on whether your airframe is well balanced, and your
flying style.</string> flying style.</string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.100000000000000</double> <double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="3"> <item row="7" column="3">
<widget class="QDoubleSpinBox" name="yawKi"> <widget class="QDoubleSpinBox" name="yawKi">
<property name="toolTip"> <property name="toolTip">
<string>Ki can usually be almost identical to Kp.</string> <string>Ki can usually be almost identical to Kp.</string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.100000000000000</double> <double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="2"> <item row="7" column="2">
<widget class="QDoubleSpinBox" name="yawKp"> <widget class="QDoubleSpinBox" name="yawKp">
<property name="toolTip"> <property name="toolTip">
<string>Once Rate stabilization is done, you should increase the Kp factor until the airframe oscillates again, and go back down 20% or so. <string>Once Rate stabilization is done, you should increase the Kp factor until the airframe oscillates again, and go back down 20% or so.
</string> </string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.100000000000000</double> <double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="2"> <item row="6" column="2">
<widget class="QDoubleSpinBox" name="pitchKp"> <widget class="QDoubleSpinBox" name="pitchKp">
<property name="toolTip"> <property name="toolTip">
<string>Once Rate stabilization is done, you should increase the Kp factor until the airframe oscillates again, and go back down 20% or so. <string>Once Rate stabilization is done, you should increase the Kp factor until the airframe oscillates again, and go back down 20% or so.
</string> </string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.100000000000000</double> <double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="7" column="1">
<widget class="QLabel" name="label_18"> <widget class="QLabel" name="label_18">
<property name="text"> <property name="text">
<string>Yaw</string> <string>Yaw</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="6" column="1">
<widget class="QLabel" name="label_17"> <widget class="QLabel" name="label_17">
<property name="text"> <property name="text">
<string>Pitch</string> <string>Pitch</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
<widget class="QLabel" name="label_16"> <widget class="QLabel" name="label_16">
<property name="text"> <property name="text">
<string>Roll</string> <string>Roll</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="3"> <item row="6" column="3">
<widget class="QDoubleSpinBox" name="pitchKi"> <widget class="QDoubleSpinBox" name="pitchKi">
<property name="toolTip"> <property name="toolTip">
<string>Ki can usually be almost identical to Kp.</string> <string>Ki can usually be almost identical to Kp.</string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.100000000000000</double> <double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="4"> <item row="6" column="4">
<widget class="QDoubleSpinBox" name="pitchILimit"> <widget class="QDoubleSpinBox" name="pitchILimit">
<property name="toolTip"> <property name="toolTip">
<string>ILimit can be equal to three to four times Ki, but you can adjust <string>ILimit can be equal to three to four times Ki, but you can adjust
depending on whether your airframe is well balanced, and your depending on whether your airframe is well balanced, and your
flying style.</string> flying style.</string>
</property> </property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.100000000000000</double> <double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0"> <item row="6" column="0">
<widget class="QCheckBox" name="linkAttitudeRP"> <widget class="QCheckBox" name="linkAttitudeRP">
<property name="toolTip"> <property name="toolTip">
<string>If checked, the Roll and Pitch factors will be identical. <string>If checked, the Roll and Pitch factors will be identical.
When you change one, the other is updated.</string> When you change one, the other is updated.</string>
</property> </property>
<property name="text"> <property name="text">
<string>Link</string> <string>Link</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>Stick range and limits</string>
</property>
<layout class="QGridLayout" name="gridLayout" rowminimumheight="5,5,5,5">
<property name="sizeConstraint">
<enum>QLayout::SetMinAndMaxSize</enum>
</property>
<item row="0" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>Roll</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Pitch</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_23">
<property name="text">
<string>Yaw</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="rollMax">
<property name="maximum">
<number>180</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="pitchMax">
<property name="maximum">
<number>180</number>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="yawMax">
<property name="maximum">
<number>180</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Full stick angle (deg)</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Full stick rate (deg/s)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="manualRoll">
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="manualPitch">
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QSpinBox" name="manualYaw">
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_24">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string notr="true"/>
</property>
<property name="text">
<string>Maximum rate in attitude mode (deg/s)</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="maximumRoll">
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="maximumPitch">
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QSpinBox" name="maximumYaw">
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="lowThrottleZeroIntegral">
<property name="text">
<string>Zero the integral when throttle is low</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>Stick range and limits</string>
</property>
<layout class="QGridLayout" name="gridLayout" rowminimumheight="5,5,5,5">
<property name="sizeConstraint">
<enum>QLayout::SetMinAndMaxSize</enum>
</property>
<item row="0" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>Roll</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Pitch</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_23">
<property name="text">
<string>Yaw</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="rollMax">
<property name="maximum">
<number>180</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="pitchMax">
<property name="maximum">
<number>180</number>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="yawMax">
<property name="maximum">
<number>180</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Full stick angle (deg)</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Full stick rate (deg/s)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="manualRoll">
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="manualPitch">
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QSpinBox" name="manualYaw">
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_24">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="toolTip">
<string notr="true"/>
</property>
<property name="text">
<string>Maximum rate in attitude mode (deg/s)</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="maximumRoll">
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="maximumPitch">
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QSpinBox" name="maximumYaw">
<property name="maximum">
<number>300</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="lowThrottleZeroIntegral">
<property name="text">
<string>Zero the integral when throttle is low</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>

View File

@ -27,6 +27,7 @@
#include "pfdgadgetwidget.h" #include "pfdgadgetwidget.h"
#include <utils/stylehelper.h> #include <utils/stylehelper.h>
#include <utils/cachedsvgitem.h>
#include <iostream> #include <iostream>
#include <QDebug> #include <QDebug>
#include <QPainter> #include <QPainter>
@ -383,7 +384,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
- Battery stats: battery-txt - Battery stats: battery-txt
*/ */
l_scene->clear(); // Deletes all items contained in the scene as well. l_scene->clear(); // Deletes all items contained in the scene as well.
m_background = new QGraphicsSvgItem(); m_background = new CachedSvgItem();
// All other items will be clipped to the shape of the background // All other items will be clipped to the shape of the background
m_background->setFlags(QGraphicsItem::ItemClipsChildrenToShape| m_background->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
QGraphicsItem::ItemClipsToShape); QGraphicsItem::ItemClipsToShape);
@ -391,28 +392,28 @@ void PFDGadgetWidget::setDialFile(QString dfn)
m_background->setElementId("background"); m_background->setElementId("background");
l_scene->addItem(m_background); l_scene->addItem(m_background);
m_world = new QGraphicsSvgItem(); m_world = new CachedSvgItem();
m_world->setParentItem(m_background); m_world->setParentItem(m_background);
m_world->setSharedRenderer(m_renderer); m_world->setSharedRenderer(m_renderer);
m_world->setElementId("world"); m_world->setElementId("world");
l_scene->addItem(m_world); l_scene->addItem(m_world);
// red Roll scale: rollscale // red Roll scale: rollscale
m_rollscale = new QGraphicsSvgItem(); m_rollscale = new CachedSvgItem();
m_rollscale->setSharedRenderer(m_renderer); m_rollscale->setSharedRenderer(m_renderer);
m_rollscale->setElementId("rollscale"); m_rollscale->setElementId("rollscale");
l_scene->addItem(m_rollscale); l_scene->addItem(m_rollscale);
// Home point: // Home point:
m_homewaypoint = new QGraphicsSvgItem(); m_homewaypoint = new CachedSvgItem();
// Next point: // Next point:
m_nextwaypoint = new QGraphicsSvgItem(); m_nextwaypoint = new CachedSvgItem();
// Home point bearing: // Home point bearing:
m_homepointbearing = new QGraphicsSvgItem(); m_homepointbearing = new CachedSvgItem();
// Next point bearing: // Next point bearing:
m_nextpointbearing = new QGraphicsSvgItem(); m_nextpointbearing = new CachedSvgItem();
QGraphicsSvgItem *m_foreground = new QGraphicsSvgItem(); QGraphicsSvgItem *m_foreground = new CachedSvgItem();
m_foreground->setParentItem(m_background); m_foreground->setParentItem(m_background);
m_foreground->setSharedRenderer(m_renderer); m_foreground->setSharedRenderer(m_renderer);
m_foreground->setElementId("foreground"); m_foreground->setElementId("foreground");
@ -429,7 +430,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
// into a QGraphicsSvgItem which we will display at the same // into a QGraphicsSvgItem which we will display at the same
// place: we do this so that the heading scale can be clipped to // place: we do this so that the heading scale can be clipped to
// the compass dial region. // the compass dial region.
m_compass = new QGraphicsSvgItem(); m_compass = new CachedSvgItem();
m_compass->setSharedRenderer(m_renderer); m_compass->setSharedRenderer(m_renderer);
m_compass->setElementId("compass"); m_compass->setElementId("compass");
m_compass->setFlags(QGraphicsItem::ItemClipsChildrenToShape| m_compass->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
@ -440,7 +441,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
m_compass->setTransform(matrix,false); m_compass->setTransform(matrix,false);
// Now place the compass scale inside: // Now place the compass scale inside:
m_compassband = new QGraphicsSvgItem(); m_compassband = new CachedSvgItem();
m_compassband->setSharedRenderer(m_renderer); m_compassband->setSharedRenderer(m_renderer);
m_compassband->setElementId("compass-band"); m_compassband->setElementId("compass-band");
m_compassband->setParentItem(m_compass); m_compassband->setParentItem(m_compass);
@ -462,7 +463,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
compassMatrix = m_renderer->matrixForElement("speed-bg"); compassMatrix = m_renderer->matrixForElement("speed-bg");
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-bg")).x(); startX = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-bg")).x();
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-bg")).y(); startY = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-bg")).y();
QGraphicsSvgItem *verticalbg = new QGraphicsSvgItem(); QGraphicsSvgItem *verticalbg = new CachedSvgItem();
verticalbg->setSharedRenderer(m_renderer); verticalbg->setSharedRenderer(m_renderer);
verticalbg->setElementId("speed-bg"); verticalbg->setElementId("speed-bg");
verticalbg->setFlags(QGraphicsItem::ItemClipsChildrenToShape| verticalbg->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
@ -477,7 +478,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
m_speedscale = new QGraphicsItemGroup(); m_speedscale = new QGraphicsItemGroup();
m_speedscale->setParentItem(verticalbg); m_speedscale->setParentItem(verticalbg);
QGraphicsSvgItem *speedscalelines = new QGraphicsSvgItem(); QGraphicsSvgItem *speedscalelines = new CachedSvgItem();
speedscalelines->setSharedRenderer(m_renderer); speedscalelines->setSharedRenderer(m_renderer);
speedscalelines->setElementId("speed-scale"); speedscalelines->setElementId("speed-scale");
speedScaleHeight = m_renderer->matrixForElement("speed-scale").mapRect( speedScaleHeight = m_renderer->matrixForElement("speed-scale").mapRect(
@ -523,7 +524,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-window")).x(); startX = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-window")).x();
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-window")).y(); startY = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-window")).y();
qreal speedWindowHeight = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-window")).height(); qreal speedWindowHeight = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-window")).height();
QGraphicsSvgItem *speedwindow = new QGraphicsSvgItem(); QGraphicsSvgItem *speedwindow = new CachedSvgItem();
speedwindow->setSharedRenderer(m_renderer); speedwindow->setSharedRenderer(m_renderer);
speedwindow->setElementId("speed-window"); speedwindow->setElementId("speed-window");
speedwindow->setFlags(QGraphicsItem::ItemClipsChildrenToShape| speedwindow->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
@ -548,7 +549,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
compassMatrix = m_renderer->matrixForElement("altitude-bg"); compassMatrix = m_renderer->matrixForElement("altitude-bg");
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-bg")).x(); startX = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-bg")).x();
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-bg")).y(); startY = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-bg")).y();
verticalbg = new QGraphicsSvgItem(); verticalbg = new CachedSvgItem();
verticalbg->setSharedRenderer(m_renderer); verticalbg->setSharedRenderer(m_renderer);
verticalbg->setElementId("altitude-bg"); verticalbg->setElementId("altitude-bg");
verticalbg->setFlags(QGraphicsItem::ItemClipsChildrenToShape| verticalbg->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
@ -563,7 +564,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
m_altitudescale = new QGraphicsItemGroup(); m_altitudescale = new QGraphicsItemGroup();
m_altitudescale->setParentItem(verticalbg); m_altitudescale->setParentItem(verticalbg);
QGraphicsSvgItem *altitudescalelines = new QGraphicsSvgItem(); QGraphicsSvgItem *altitudescalelines = new CachedSvgItem();
altitudescalelines->setSharedRenderer(m_renderer); altitudescalelines->setSharedRenderer(m_renderer);
altitudescalelines->setElementId("altitude-scale"); altitudescalelines->setElementId("altitude-scale");
altitudeScaleHeight = m_renderer->matrixForElement("altitude-scale").mapRect( altitudeScaleHeight = m_renderer->matrixForElement("altitude-scale").mapRect(
@ -604,7 +605,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-window")).x(); startX = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-window")).x();
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-window")).y(); startY = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-window")).y();
qreal altitudeWindowHeight = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-window")).height(); qreal altitudeWindowHeight = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-window")).height();
QGraphicsSvgItem *altitudewindow = new QGraphicsSvgItem(); QGraphicsSvgItem *altitudewindow = new CachedSvgItem();
altitudewindow->setSharedRenderer(m_renderer); altitudewindow->setSharedRenderer(m_renderer);
altitudewindow->setElementId("altitude-window"); altitudewindow->setElementId("altitude-window");
altitudewindow->setFlags(QGraphicsItem::ItemClipsChildrenToShape| altitudewindow->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
@ -633,7 +634,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
compassMatrix = m_renderer->matrixForElement("gcstelemetry-Disconnected"); compassMatrix = m_renderer->matrixForElement("gcstelemetry-Disconnected");
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).x(); startX = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).x();
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).y(); startY = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).y();
gcsTelemetryArrow = new QGraphicsSvgItem(); gcsTelemetryArrow = new CachedSvgItem();
gcsTelemetryArrow->setSharedRenderer(m_renderer); gcsTelemetryArrow->setSharedRenderer(m_renderer);
gcsTelemetryArrow->setElementId("gcstelemetry-Disconnected"); gcsTelemetryArrow->setElementId("gcstelemetry-Disconnected");
l_scene->addItem(gcsTelemetryArrow); l_scene->addItem(gcsTelemetryArrow);
@ -669,7 +670,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
compassMatrix = m_renderer->matrixForElement("gcstelemetry-Disconnected"); compassMatrix = m_renderer->matrixForElement("gcstelemetry-Disconnected");
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).x(); startX = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).x();
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).y(); startY = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).y();
gcsTelemetryArrow = new QGraphicsSvgItem(); gcsTelemetryArrow = new CachedSvgItem();
gcsTelemetryArrow->setSharedRenderer(m_renderer); gcsTelemetryArrow->setSharedRenderer(m_renderer);
gcsTelemetryArrow->setElementId("gcstelemetry-Disconnected"); gcsTelemetryArrow->setElementId("gcstelemetry-Disconnected");
l_scene->addItem(gcsTelemetryArrow); l_scene->addItem(gcsTelemetryArrow);
@ -702,7 +703,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
compassMatrix = m_renderer->matrixForElement("gcstelemetry-Disconnected"); compassMatrix = m_renderer->matrixForElement("gcstelemetry-Disconnected");
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).x(); startX = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).x();
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).y(); startY = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).y();
gcsTelemetryArrow = new QGraphicsSvgItem(); gcsTelemetryArrow = new CachedSvgItem();
gcsTelemetryArrow->setSharedRenderer(m_renderer); gcsTelemetryArrow->setSharedRenderer(m_renderer);
gcsTelemetryArrow->setElementId("gcstelemetry-Disconnected"); gcsTelemetryArrow->setElementId("gcstelemetry-Disconnected");
l_scene->addItem(gcsTelemetryArrow); l_scene->addItem(gcsTelemetryArrow);
@ -771,7 +772,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
{ qDebug()<<"Error on PFD artwork file."; { qDebug()<<"Error on PFD artwork file.";
m_renderer->load(QString(":/pfd/images/pfd-default.svg")); m_renderer->load(QString(":/pfd/images/pfd-default.svg"));
l_scene->clear(); // This also deletes all items contained in the scene. l_scene->clear(); // This also deletes all items contained in the scene.
m_background = new QGraphicsSvgItem(); m_background = new CachedSvgItem();
m_background->setSharedRenderer(m_renderer); m_background->setSharedRenderer(m_renderer);
l_scene->addItem(m_background); l_scene->addItem(m_background);
pfdError = true; pfdError = true;

View File

@ -4,6 +4,7 @@
<field name="CC_FlexiPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,GPS,Spektrum,ComAux,I2C" defaultvalue="Disabled"/> <field name="CC_FlexiPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,GPS,Spektrum,ComAux,I2C" defaultvalue="Disabled"/>
<field name="CC_MainPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,S.Bus,GPS,Spektrum,ComAux" defaultvalue="Telemetry"/> <field name="CC_MainPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,S.Bus,GPS,Spektrum,ComAux" defaultvalue="Telemetry"/>
<field name="OptionalModules" units="" type="enum" elementnames="CameraStab,GPS" options="Disabled,Enabled" defaultvalue="Disabled"/> <field name="OptionalModules" units="" type="enum" elementnames="CameraStab,GPS" options="Disabled,Enabled" defaultvalue="Disabled"/>
<field name="DSMxBind" units="" type="uint8" elements="1" defaultvalue="0"/>
<access gcs="readwrite" flight="readwrite"/> <access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="true" updatemode="onchange" period="0"/> <telemetrygcs acked="true" updatemode="onchange" period="0"/>
<telemetryflight acked="true" updatemode="onchange" period="0"/> <telemetryflight acked="true" updatemode="onchange" period="0"/>

View File

@ -1,7 +1,7 @@
<xml> <xml>
<object name="ObjectPersistence" singleinstance="true" settings="false"> <object name="ObjectPersistence" singleinstance="true" settings="false">
<description>Someone who knows please enter this</description> <description>Someone who knows please enter this</description>
<field name="Operation" units="" type="enum" elements="1" options="NOP,Load,Save,Delete,Completed"/> <field name="Operation" units="" type="enum" elements="1" options="NOP,Load,Save,Delete,FullErase,Completed"/>
<field name="Selection" units="" type="enum" elements="1" options="SingleObject,AllSettings,AllMetaObjects,AllObjects"/> <field name="Selection" units="" type="enum" elements="1" options="SingleObject,AllSettings,AllMetaObjects,AllObjects"/>
<field name="ObjectID" units="" type="uint32" elements="1"/> <field name="ObjectID" units="" type="uint32" elements="1"/>
<field name="InstanceID" units="" type="uint32" elements="1"/> <field name="InstanceID" units="" type="uint32" elements="1"/>