1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-01 09:24:10 +01:00

Merge branch 'next' into theothercliff/OP-1259_Cruise_Control_Tweaks

This commit is contained in:
Cliff Geerdes 2014-03-26 13:49:17 -04:00
commit 45fa3220a5
20 changed files with 244 additions and 168 deletions

View File

@ -450,11 +450,25 @@ else
GCS_SILENT := silent GCS_SILENT := silent
endif endif
.NOTPARALLEL:
.PHONY: openpilotgcs .PHONY: openpilotgcs
openpilotgcs: uavobjects_gcs openpilotgcs: uavobjects_gcs openpilotgcs_qmake openpilotgcs_make
$(V1) $(MKDIR) -p $(BUILD_DIR)/$@_$(GCS_BUILD_CONF)
$(V1) ( cd $(BUILD_DIR)/$@_$(GCS_BUILD_CONF) && \ .PHONY: openpilotgcs_qmake
$(QMAKE) $(ROOT_DIR)/ground/openpilotgcs/openpilotgcs.pro -spec $(QT_SPEC) -r CONFIG+="$(GCS_BUILD_CONF) $(GCS_SILENT)" $(GCS_QMAKE_OPTS) && \ openpilotgcs_qmake:
ifeq ($(QMAKE_SKIP),)
$(V1) $(MKDIR) -p $(BUILD_DIR)/openpilotgcs_$(GCS_BUILD_CONF)
$(V1) ( cd $(BUILD_DIR)/openpilotgcs_$(GCS_BUILD_CONF) && \
$(QMAKE) $(ROOT_DIR)/ground/openpilotgcs/openpilotgcs.pro -spec $(QT_SPEC) -r CONFIG+="$(GCS_BUILD_CONF) $(GCS_SILENT)" $(GCS_QMAKE_OPTS) \
)
else
@$(ECHO) "skipping qmake"
endif
.PHONY: openpilotgcs_make
openpilotgcs_make:
$(V1) $(MKDIR) -p $(BUILD_DIR)/openpilotgcs_$(GCS_BUILD_CONF)
$(V1) ( cd $(BUILD_DIR)/openpilotgcs_$(GCS_BUILD_CONF)/$(MAKE_DIR) && \
$(MAKE) -w ; \ $(MAKE) -w ; \
) )
@ -947,6 +961,9 @@ help:
@$(ECHO) @$(ECHO)
@$(ECHO) " [GCS]" @$(ECHO) " [GCS]"
@$(ECHO) " gcs - Build the Ground Control System (GCS) application (debug|release)" @$(ECHO) " gcs - Build the Ground Control System (GCS) application (debug|release)"
@$(ECHO) " Skip qmake: QMAKE_SKIP=1"
@$(ECHO) " Compile specific directory: MAKE_DIR=<dir>"
@$(ECHO) " Example: make gcs QMAKE_SKIP=1 MAKE_DIR=src/plugins/coreplugin"
@$(ECHO) " gcs_clean - Remove the Ground Control System (GCS) application (debug|release)" @$(ECHO) " gcs_clean - Remove the Ground Control System (GCS) application (debug|release)"
@$(ECHO) " Supported build configurations: GCS_BUILD_CONF=debug|release (default is $(GCS_BUILD_CONF))" @$(ECHO) " Supported build configurations: GCS_BUILD_CONF=debug|release (default is $(GCS_BUILD_CONF))"
@$(ECHO) @$(ECHO)

View File

@ -63,8 +63,6 @@
// Private types // Private types
// Private variables // Private variables
static uint32_t idleCounter;
static uint32_t idleCounterClear;
static xTaskHandle systemTaskHandle; static xTaskHandle systemTaskHandle;
static bool stackOverflow; static bool stackOverflow;
static bool mallocFailed; static bool mallocFailed;
@ -130,8 +128,6 @@ static void systemTask(__attribute__((unused)) void *parameters)
} }
// Initialize vars // Initialize vars
idleCounter = 0;
idleCounterClear = 0;
lastSysTime = xTaskGetTickCount(); lastSysTime = xTaskGetTickCount();
// Main system loop // Main system loop
@ -205,15 +201,7 @@ static void systemTask(__attribute__((unused)) void *parameters)
* Called by the RTOS when the CPU is idle, used to measure the CPU idle time. * Called by the RTOS when the CPU is idle, used to measure the CPU idle time.
*/ */
void vApplicationIdleHook(void) void vApplicationIdleHook(void)
{ {}
// Called when the scheduler has no tasks to run
if (idleCounterClear == 0) {
++idleCounter;
} else {
idleCounter = 0;
idleCounterClear = 0;
}
}
/** /**
* Called by the RTOS when a stack overflow is detected. * Called by the RTOS when a stack overflow is detected.

View File

@ -92,8 +92,6 @@
// Private types // Private types
// Private variables // Private variables
static uint32_t idleCounter;
static uint32_t idleCounterClear;
static xTaskHandle systemTaskHandle; static xTaskHandle systemTaskHandle;
static xQueueHandle objectPersistenceQueue; static xQueueHandle objectPersistenceQueue;
static enum { STACKOVERFLOW_NONE = 0, STACKOVERFLOW_WARNING = 1, STACKOVERFLOW_CRITICAL = 3 } stackOverflow; static enum { STACKOVERFLOW_NONE = 0, STACKOVERFLOW_WARNING = 1, STACKOVERFLOW_CRITICAL = 3 } stackOverflow;
@ -132,6 +130,7 @@ int32_t SystemModStart(void)
// Register task // Register task
PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_SYSTEM, systemTaskHandle); PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_SYSTEM, systemTaskHandle);
return 0; return 0;
} }
@ -186,15 +185,12 @@ static void systemTask(__attribute__((unused)) void *parameters)
*/ */
PIOS_SYS_Reset(); PIOS_SYS_Reset();
} }
#if defined(PIOS_INCLUDE_IAP) #if defined(PIOS_INCLUDE_IAP)
/* Record a successful boot */ /* Record a successful boot */
PIOS_IAP_WriteBootCount(0); PIOS_IAP_WriteBootCount(0);
#endif #endif
// Initialize vars // Initialize vars
idleCounter = 0;
idleCounterClear = 0;
// Listen for SettingPersistance object updates, connect a callback function // Listen for SettingPersistance object updates, connect a callback function
ObjectPersistenceConnectQueue(objectPersistenceQueue); ObjectPersistenceConnectQueue(objectPersistenceQueue);
@ -212,9 +208,10 @@ static void systemTask(__attribute__((unused)) void *parameters)
// Main system loop // Main system loop
while (1) { while (1) {
// Update the system statistics // Update the system statistics
updateStats();
cycleCount = cycleCount > 0 ? cycleCount - 1 : 7;
cycleCount = cycleCount > 0 ? cycleCount - 1 : 7;
// if(cycleCount == 1){
updateStats();
// Update the system alarms // Update the system alarms
updateSystemAlarms(); updateSystemAlarms();
#ifdef DIAG_I2C_WDG_STATS #ifdef DIAG_I2C_WDG_STATS
@ -227,10 +224,12 @@ static void systemTask(__attribute__((unused)) void *parameters)
PIOS_TASK_MONITOR_ForEachTask(taskMonitorForEachCallback, &taskInfoData); PIOS_TASK_MONITOR_ForEachTask(taskMonitorForEachCallback, &taskInfoData);
TaskInfoSet(&taskInfoData); TaskInfoSet(&taskInfoData);
// Update the callback status object // Update the callback status object
// if(FALSE){
PIOS_CALLBACKSCHEDULER_ForEachCallback(callbackSchedulerForEachCallback, &callbackInfoData); PIOS_CALLBACKSCHEDULER_ForEachCallback(callbackSchedulerForEachCallback, &callbackInfoData);
CallbackInfoSet(&callbackInfoData); CallbackInfoSet(&callbackInfoData);
// }
#endif #endif
// }
// Flash the heartbeat LED // Flash the heartbeat LED
#if defined(PIOS_LED_HEARTBEAT) #if defined(PIOS_LED_HEARTBEAT)
uint8_t armingStatus; uint8_t armingStatus;
@ -541,7 +540,6 @@ static uint16_t GetFreeIrqStackSize(void)
*/ */
static void updateStats() static void updateStats()
{ {
static portTickType lastTickCount = 0;
SystemStatsData stats; SystemStatsData stats;
// Get stats and update // Get stats and update
@ -559,10 +557,6 @@ static void updateStats()
// Get Irq stack status // Get Irq stack status
stats.IRQStackRemaining = GetFreeIrqStackSize(); stats.IRQStackRemaining = GetFreeIrqStackSize();
// When idleCounterClear was not reset by the idle-task, it means the idle-task did not run
if (idleCounterClear) {
idleCounter = 0;
}
#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32) #if !defined(ARCH_POSIX) && !defined(ARCH_WIN32)
if (pios_uavo_settings_fs_id) { if (pios_uavo_settings_fs_id) {
PIOS_FLASHFS_GetStats(pios_uavo_settings_fs_id, &fsStats); PIOS_FLASHFS_GetStats(pios_uavo_settings_fs_id, &fsStats);
@ -575,16 +569,11 @@ static void updateStats()
stats.UsrSlotsActive = fsStats.num_active_slots; stats.UsrSlotsActive = fsStats.num_active_slots;
} }
#endif #endif
portTickType now = xTaskGetTickCount(); stats.CPULoad = 100 - PIOS_TASK_MONITOR_GetIdlePercentage();
if (now > lastTickCount) {
uint32_t dT = (xTaskGetTickCount() - lastTickCount) * portTICK_RATE_MS; // in ms
stats.CPULoad = 100 - (uint8_t)roundf(100.0f * ((float)idleCounter / ((float)dT / 1000.0f)) / (float)IDLE_COUNTS_PER_SEC_AT_NO_LOAD);
} // else: TickCount has wrapped, do not calc now
lastTickCount = now;
idleCounterClear = 1;
#if defined(PIOS_INCLUDE_ADC) && defined(PIOS_ADC_USE_TEMP_SENSOR) #if defined(PIOS_INCLUDE_ADC) && defined(PIOS_ADC_USE_TEMP_SENSOR)
float temp_voltage = PIOS_ADC_PinGetVolt(PIOS_ADC_TEMPERATURE_PIN); float temp_voltage = PIOS_ADC_PinGetVolt(PIOS_ADC_TEMPERATURE_PIN);
stats.CPUTemp = PIOS_CONVERT_VOLT_TO_CPU_TEMP(temp_voltage);; stats.CPUTemp = PIOS_CONVERT_VOLT_TO_CPU_TEMP(temp_voltage);;
#endif #endif
SystemStatsSet(&stats); SystemStatsSet(&stats);
} }
@ -663,15 +652,7 @@ static void updateSystemAlarms()
* Called by the RTOS when the CPU is idle, used to measure the CPU idle time. * Called by the RTOS when the CPU is idle, used to measure the CPU idle time.
*/ */
void vApplicationIdleHook(void) void vApplicationIdleHook(void)
{ {}
// Called when the scheduler has no tasks to run
if (idleCounterClear == 0) {
++idleCounter;
} else {
idleCounter = 0;
idleCounterClear = 0;
}
}
/** /**
* Called by the RTOS when a stack overflow is detected. * Called by the RTOS when a stack overflow is detected.

View File

@ -33,6 +33,7 @@
static xSemaphoreHandle mLock; static xSemaphoreHandle mLock;
static xTaskHandle *mTaskHandles; static xTaskHandle *mTaskHandles;
static uint32_t mLastMonitorTime; static uint32_t mLastMonitorTime;
static uint32_t mLastIdleMonitorTime;
static uint16_t mMaxTasks; static uint16_t mMaxTasks;
/** /**
@ -53,9 +54,11 @@ int32_t PIOS_TASK_MONITOR_Initialize(uint16_t max_tasks)
mMaxTasks = max_tasks; mMaxTasks = max_tasks;
#if (configGENERATE_RUN_TIME_STATS == 1) #if (configGENERATE_RUN_TIME_STATS == 1)
mLastMonitorTime = portGET_RUN_TIME_COUNTER_VALUE(); mLastMonitorTime = portGET_RUN_TIME_COUNTER_VALUE();
mLastIdleMonitorTime = portGET_RUN_TIME_COUNTER_VALUE();
#else #else
mLastMonitorTime = 0; mLastMonitorTime = 0;
mLastIdleMonitorTime = 0;
#endif #endif
return 0; return 0;
} }
@ -146,4 +149,31 @@ void PIOS_TASK_MONITOR_ForEachTask(TaskMonitorTaskInfoCallback callback, void *c
xSemaphoreGiveRecursive(mLock); xSemaphoreGiveRecursive(mLock);
} }
uint8_t PIOS_TASK_MONITOR_GetIdlePercentage()
{
#if defined(ARCH_POSIX) || defined(ARCH_WIN32)
return 50;
#elif (configGENERATE_RUN_TIME_STATS == 1)
xSemaphoreTakeRecursive(mLock, portMAX_DELAY);
uint32_t currentTime = portGET_RUN_TIME_COUNTER_VALUE();
/* avoid divide-by-zero if the interval is too small */
uint32_t deltaTime = ((currentTime - mLastIdleMonitorTime) / 100) ? : 1;
mLastIdleMonitorTime = currentTime;
uint8_t running_time_percentage = 0;
/* Generate idle time percentage stats */
running_time_percentage = uxTaskGetRunTime(xTaskGetIdleTaskHandle()) / deltaTime;
xSemaphoreGiveRecursive(mLock);
return running_time_percentage;
#else
return 0;
#endif
}
#endif // PIOS_INCLUDE_TASK_MONITOR #endif // PIOS_INCLUDE_TASK_MONITOR

View File

@ -104,4 +104,9 @@ typedef void (*TaskMonitorTaskInfoCallback)(uint16_t task_id, const struct pios_
*/ */
extern void PIOS_TASK_MONITOR_ForEachTask(TaskMonitorTaskInfoCallback callback, void *context); extern void PIOS_TASK_MONITOR_ForEachTask(TaskMonitorTaskInfoCallback callback, void *context);
/**
* Return the idle task running time percentage.
*/
extern uint8_t PIOS_TASK_MONITOR_GetIdlePercentage();
#endif // PIOS_TASK_MONITOR_H #endif // PIOS_TASK_MONITOR_H

View File

@ -75,11 +75,9 @@
#endif #endif
/* Enable run time stats collection */ /* Enable run time stats collection */
#ifdef DIAG_TASKS
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configGENERATE_RUN_TIME_STATS 1 #define configGENERATE_RUN_TIME_STATS 1
#define INCLUDE_uxTaskGetRunTime 1 #define INCLUDE_uxTaskGetRunTime 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() \ #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() \
do { \ do { \
(*(unsigned long *)0xe000edfc) |= (1 << 24); /* DEMCR |= DEMCR_TRCENA */ \ (*(unsigned long *)0xe000edfc) |= (1 << 24); /* DEMCR |= DEMCR_TRCENA */ \
@ -87,6 +85,9 @@
} \ } \
while (0) while (0)
#define portGET_RUN_TIME_COUNTER_VALUE() (*(unsigned long *)0xe0001004) /* DWT_CYCCNT */ #define portGET_RUN_TIME_COUNTER_VALUE() (*(unsigned long *)0xe0001004) /* DWT_CYCCNT */
#ifdef DIAG_TASKS
#define configCHECK_FOR_STACK_OVERFLOW 2
#else #else
#define configCHECK_FOR_STACK_OVERFLOW 1 #define configCHECK_FOR_STACK_OVERFLOW 1
#endif #endif

View File

@ -75,11 +75,9 @@
#endif #endif
/* Enable run time stats collection */ /* Enable run time stats collection */
#ifdef DIAG_TASKS
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configGENERATE_RUN_TIME_STATS 1 #define configGENERATE_RUN_TIME_STATS 1
#define INCLUDE_uxTaskGetRunTime 1 #define INCLUDE_uxTaskGetRunTime 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() \ #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() \
do { \ do { \
(*(unsigned long *)0xe000edfc) |= (1 << 24); /* DEMCR |= DEMCR_TRCENA */ \ (*(unsigned long *)0xe000edfc) |= (1 << 24); /* DEMCR |= DEMCR_TRCENA */ \
@ -87,6 +85,9 @@
} \ } \
while (0) while (0)
#define portGET_RUN_TIME_COUNTER_VALUE() (*(unsigned long *)0xe0001004) /* DWT_CYCCNT */ #define portGET_RUN_TIME_COUNTER_VALUE() (*(unsigned long *)0xe0001004) /* DWT_CYCCNT */
#ifdef DIAG_TASKS
#define configCHECK_FOR_STACK_OVERFLOW 2
#else #else
#define configCHECK_FOR_STACK_OVERFLOW 1 #define configCHECK_FOR_STACK_OVERFLOW 1
#endif #endif

View File

@ -79,6 +79,7 @@
/* Enable run time stats collection */ /* Enable run time stats collection */
#define configGENERATE_RUN_TIME_STATS 1 #define configGENERATE_RUN_TIME_STATS 1
#define INCLUDE_uxTaskGetRunTime 1 #define INCLUDE_uxTaskGetRunTime 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
/* /*
* Once we move to CMSIS2 we can at least use: * Once we move to CMSIS2 we can at least use:

View File

@ -64,6 +64,7 @@
#define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255 /* This is the raw value as per the Cortex-M3 NVIC. Values can be 255
(lowest) to 1 (highest maskable) to 0 (highest non-maskable). */ (lowest) to 1 (highest maskable) to 0 (highest non-maskable). */

View File

@ -79,6 +79,7 @@
/* Enable run time stats collection */ /* Enable run time stats collection */
#define configGENERATE_RUN_TIME_STATS 1 #define configGENERATE_RUN_TIME_STATS 1
#define INCLUDE_uxTaskGetRunTime 1 #define INCLUDE_uxTaskGetRunTime 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
/* /*
* Once we move to CMSIS2 we can at least use: * Once we move to CMSIS2 we can at least use:

View File

@ -13378,6 +13378,7 @@ border-radius: 5;</string>
<property name="decimals"> <property name="decimals">
<number>5</number> <number>5</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<double>0.000100000000000</double> <double>0.000100000000000</double>
@ -15942,6 +15943,7 @@ border-radius: 5;</string>
<string>element:Kp</string> <string>element:Kp</string>
<string>haslimits:no</string> <string>haslimits:no</string>
<string>scale:1</string> <string>scale:1</string>
<string>buttongroup:5,20</string> <string>buttongroup:5,20</string>
</stringlist> </stringlist>
</property> </property>
@ -17353,6 +17355,7 @@ border-radius: 5;</string>
<red>26</red> <red>26</red>
<green>26</green> <green>26</green>
<blue>26</blue> <blue>26</blue>
</color> </color>
</brush> </brush>
</colorrole> </colorrole>
@ -24307,6 +24310,7 @@ border-radius: 5;</string>
<string>buttongroup:16</string> <string>buttongroup:16</string>
</stringlist> </stringlist>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">

View File

@ -121,6 +121,10 @@ void UAVGadgetDecorator::saveState(QSettings *qSettings)
if (m_activeConfiguration) { if (m_activeConfiguration) {
qSettings->setValue("activeConfiguration", m_activeConfiguration->name()); qSettings->setValue("activeConfiguration", m_activeConfiguration->name());
} }
// save gadget individual state
qSettings->beginGroup("state");
m_gadget->saveState(qSettings);
qSettings->endGroup();
} }
void UAVGadgetDecorator::restoreState(QSettings *qSettings) void UAVGadgetDecorator::restoreState(QSettings *qSettings)
@ -134,4 +138,8 @@ void UAVGadgetDecorator::restoreState(QSettings *qSettings)
break; break;
} }
} }
// restore gadget individual state
qSettings->beginGroup("state");
m_gadget->restoreState(qSettings);
qSettings->endGroup();
} }

View File

@ -131,7 +131,8 @@ struct hid_device_ {
DWORD last_error_num; DWORD last_error_num;
BOOL read_pending; BOOL read_pending;
char *read_buf; char *read_buf;
OVERLAPPED ol; OVERLAPPED rx_ol;
OVERLAPPED tx_ol;
}; };
static hid_device *new_hid_device() static hid_device *new_hid_device()
@ -145,15 +146,18 @@ static hid_device *new_hid_device()
dev->last_error_num = 0; dev->last_error_num = 0;
dev->read_pending = FALSE; dev->read_pending = FALSE;
dev->read_buf = NULL; dev->read_buf = NULL;
memset(&dev->ol, 0, sizeof(dev->ol)); memset(&dev->rx_ol, 0, sizeof(dev->rx_ol));
dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*inital state f=nonsignaled*/, NULL); memset(&dev->tx_ol, 0, sizeof(dev->tx_ol));
dev->rx_ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*inital state f=nonsignaled*/, NULL);
dev->tx_ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*inital state f=nonsignaled*/, NULL);
return dev; return dev;
} }
static void free_hid_device(hid_device *dev) static void free_hid_device(hid_device *dev)
{ {
CloseHandle(dev->ol.hEvent); CloseHandle(dev->rx_ol.hEvent);
CloseHandle(dev->tx_ol.hEvent);
CloseHandle(dev->device_handle); CloseHandle(dev->device_handle);
LocalFree(dev->last_error_str); LocalFree(dev->last_error_str);
free(dev->read_buf); free(dev->read_buf);
@ -596,9 +600,7 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *
DWORD bytes_written; DWORD bytes_written;
BOOL res; BOOL res;
OVERLAPPED ol;
unsigned char *buf; unsigned char *buf;
memset(&ol, 0, sizeof(ol));
/* Make sure the right number of bytes are passed to WriteFile. Windows /* Make sure the right number of bytes are passed to WriteFile. Windows
expects the number of bytes which are in the _longest_ report (plus expects the number of bytes which are in the _longest_ report (plus
@ -618,7 +620,8 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *
length = dev->output_report_length; length = dev->output_report_length;
} }
res = WriteFile(dev->device_handle, buf, length, NULL, &ol); ResetEvent(dev->tx_ol.hEvent);
res = WriteFile(dev->device_handle, buf, length, NULL, &dev->tx_ol);
if (!res) { if (!res) {
if (GetLastError() != ERROR_IO_PENDING) { if (GetLastError() != ERROR_IO_PENDING) {
@ -631,7 +634,7 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *
/* Wait here until the write is done. This makes /* Wait here until the write is done. This makes
hid_write() synchronous. */ hid_write() synchronous. */
res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/); res = GetOverlappedResult(dev->device_handle, &dev->tx_ol, &bytes_written, TRUE/*wait*/);
if (!res) { if (!res) {
/* The Write operation failed. */ /* The Write operation failed. */
register_error(dev, "WriteFile"); register_error(dev, "WriteFile");
@ -653,14 +656,14 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char
BOOL res; BOOL res;
/* Copy the handle for convenience. */ /* Copy the handle for convenience. */
HANDLE ev = dev->ol.hEvent; HANDLE ev = dev->rx_ol.hEvent;
if (!dev->read_pending) { if (!dev->read_pending) {
/* Start an Overlapped I/O read. */ /* Start an Overlapped I/O read. */
dev->read_pending = TRUE; dev->read_pending = TRUE;
memset(dev->read_buf, 0, dev->input_report_length); memset(dev->read_buf, 0, dev->input_report_length);
ResetEvent(ev); ResetEvent(ev);
res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol); res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->rx_ol);
if (!res) { if (!res) {
if (GetLastError() != ERROR_IO_PENDING) { if (GetLastError() != ERROR_IO_PENDING) {
@ -686,7 +689,7 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char
/* Either WaitForSingleObject() told us that ReadFile has completed, or /* Either WaitForSingleObject() told us that ReadFile has completed, or
we are in non-blocking mode. Get the number of bytes read. The actual we are in non-blocking mode. Get the number of bytes read. The actual
data has been copied to the data[] array which was passed to ReadFile(). */ data has been copied to the data[] array which was passed to ReadFile(). */
res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/); res = GetOverlappedResult(dev->device_handle, &dev->rx_ol, &bytes_read, TRUE/*wait*/);
/* Set pending back to false, even if GetOverlappedResult() returned error. */ /* Set pending back to false, even if GetOverlappedResult() returned error. */
dev->read_pending = FALSE; dev->read_pending = FALSE;

View File

@ -333,26 +333,30 @@ void OPMapGadgetWidget::wpDoubleClickEvent(WayPointItem *wp)
} }
void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event) void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
{ // the user has right clicked on the map - create the pop-up context menu and display it {
QString s; // the user has right clicked on the map - create the pop-up context menu and display it
if (!m_widget || !m_map) { if (!m_widget || !m_map) {
return; return;
} }
if (event->reason() != QContextMenuEvent::Mouse) { if (event->reason() != QContextMenuEvent::Mouse) {
return; // not a mouse click event // not a mouse click event
return;
} }
// current mouse position // current mouse position
QPoint p = m_map->mapFromGlobal(event->globalPos()); QPoint p = m_map->mapFromGlobal(event->globalPos());
m_context_menu_lat_lon = m_map->GetFromLocalToLatLng(p); m_context_menu_lat_lon = m_map->GetFromLocalToLatLng(p);
if (!m_map->contentsRect().contains(p)) { if (!m_map->contentsRect().contains(p)) {
return; // the mouse click was not on the map // the mouse click was not on the map
return;
} }
// show the mouse position // show the mouse position
s = QString::number(m_context_menu_lat_lon.Lat(), 'f', 7) + " " + QString::number(m_context_menu_lat_lon.Lng(), 'f', 7); QString mousePosString = QString::number(m_context_menu_lat_lon.Lat(), 'f', 7) + " " + QString::number(m_context_menu_lat_lon.Lng(), 'f', 7);
m_widget->labelMousePos->setText(s); m_widget->labelMousePos->setText(mousePosString);
// find out if we have a waypoint under the mouse cursor // find out if we have a waypoint under the mouse cursor
QGraphicsItem *item = m_map->itemAt(p); QGraphicsItem *item = m_map->itemAt(p);
@ -364,11 +368,9 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
waypoint_locked = (m_mouse_waypoint->flags() & QGraphicsItem::ItemIsMovable) == 0; waypoint_locked = (m_mouse_waypoint->flags() & QGraphicsItem::ItemIsMovable) == 0;
} }
// ****************
// Dynamically create the popup menu // Dynamically create the popup menu
QMenu contextMenu;
contextMenu.addAction(closeAct1);
contextMenu.addSeparator();
contextMenu.addAction(reloadAct); contextMenu.addAction(reloadAct);
contextMenu.addSeparator(); contextMenu.addSeparator();
contextMenu.addAction(ripAct); contextMenu.addAction(ripAct);
@ -382,12 +384,20 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
contextMenu.addSeparator(); contextMenu.addSeparator();
QString mapMode;
switch (m_map_mode) { switch (m_map_mode) {
case Normal_MapMode: s = tr(" (Normal)"); break; case Normal_MapMode:
case MagicWaypoint_MapMode: s = tr(" (Magic Waypoint)"); break; mapMode = tr(" (Normal)");
default: s = tr(" (Unknown)"); break; break;
case MagicWaypoint_MapMode:
mapMode = tr(" (Magic Waypoint)");
break;
default:
mapMode = tr(" (Unknown)");
break;
} }
for (int i = 0; i < mapModeAct.count(); i++) { // set the menu to checked (or not) for (int i = 0; i < mapModeAct.count(); i++) {
// set the menu to checked (or not)
QAction *act = mapModeAct.at(i); QAction *act = mapModeAct.at(i);
if (!act) { if (!act) {
continue; continue;
@ -396,7 +406,7 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
act->setChecked(true); act->setChecked(true);
} }
} }
QMenu mapModeSubMenu(tr("Map mode") + s, this); QMenu mapModeSubMenu(tr("Map mode") + mapMode, this);
for (int i = 0; i < mapModeAct.count(); i++) { for (int i = 0; i < mapModeAct.count(); i++) {
mapModeSubMenu.addAction(mapModeAct.at(i)); mapModeSubMenu.addAction(mapModeAct.at(i));
} }
@ -432,7 +442,8 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
contextMenu.addAction(showUAVInfo); contextMenu.addAction(showUAVInfo);
contextMenu.addSeparator()->setText(tr("Zoom")); // Zoom section
contextMenu.addSection(tr("Zoom"));
contextMenu.addAction(zoomInAct); contextMenu.addAction(zoomInAct);
contextMenu.addAction(zoomOutAct); contextMenu.addAction(zoomOutAct);
@ -447,16 +458,16 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
contextMenu.addAction(goMouseClickAct); contextMenu.addAction(goMouseClickAct);
contextMenu.addSeparator()->setText(tr("HOME")); // Home section
contextMenu.addSection(tr("Home"));
contextMenu.addAction(setHomeAct); contextMenu.addAction(setHomeAct);
contextMenu.addAction(showHomeAct); contextMenu.addAction(showHomeAct);
contextMenu.addAction(goHomeAct); contextMenu.addAction(goHomeAct);
// ****
// uav trails // uav trails
QMenu uav_menu(tr("UAV")); QMenu uav_menu(tr("UAV"));
uav_menu.addSeparator()->setText(tr("UAV Trail")); uav_menu.addSection(tr("UAV Trail"));
contextMenu.addMenu(&uav_menu); contextMenu.addMenu(&uav_menu);
QMenu uavTrailTypeSubMenu(tr("UAV trail type") + " (" + mapcontrol::Helper::StrFromUAVTrailType(m_map->UAV->GetTrailType()) + ")", this); QMenu uavTrailTypeSubMenu(tr("UAV trail type") + " (" + mapcontrol::Helper::StrFromUAVTrailType(m_map->UAV->GetTrailType()) + ")", this);
for (int i = 0; i < uavTrailTypeAct.count(); i++) { for (int i = 0; i < uavTrailTypeAct.count(); i++) {
@ -482,22 +493,21 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
uav_menu.addAction(clearUAVtrailAct); uav_menu.addAction(clearUAVtrailAct);
// **** // UAV section
uav_menu.addSection(tr("UAV"));
uav_menu.addSeparator()->setText(tr("UAV"));
uav_menu.addAction(showUAVAct); uav_menu.addAction(showUAVAct);
uav_menu.addAction(followUAVpositionAct); uav_menu.addAction(followUAVpositionAct);
uav_menu.addAction(followUAVheadingAct); uav_menu.addAction(followUAVheadingAct);
uav_menu.addAction(goUAVAct); uav_menu.addAction(goUAVAct);
// ********* // waypoint section
#ifdef USE_PATHPLANNER #ifdef USE_PATHPLANNER
switch (m_map_mode) { switch (m_map_mode) {
case Normal_MapMode: case Normal_MapMode:
// only show the waypoint stuff if not in 'magic waypoint' mode // only show the waypoint stuff if not in 'magic waypoint' mode
contextMenu.addSeparator()->setText(tr("Waypoints")); contextMenu.addSection(tr("Waypoints"));
contextMenu.addAction(wayPointEditorAct); contextMenu.addAction(wayPointEditorAct);
contextMenu.addAction(addWayPointActFromContextMenu); contextMenu.addAction(addWayPointActFromContextMenu);
@ -515,30 +525,29 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
} }
if (m_map->WPPresent()) { if (m_map->WPPresent()) {
contextMenu.addAction(clearWayPointsAct); // we have waypoints // we have waypoints
contextMenu.addAction(clearWayPointsAct);
} }
break; break;
case MagicWaypoint_MapMode: case MagicWaypoint_MapMode:
contextMenu.addSeparator()->setText(tr("Waypoints")); contextMenu.addSection(tr("Waypoints"));
contextMenu.addAction(homeMagicWaypointAct); contextMenu.addAction(homeMagicWaypointAct);
break; break;
} }
#endif // ifdef USE_PATHPLANNER #endif // ifdef USE_PATHPLANNER
// *********
QMenu overlaySubMenu(tr("&Overlay Opacity "), this); QMenu overlaySubMenu(tr("&Overlay Opacity "), this);
for (int i = 0; i < overlayOpacityAct.count(); i++) { for (int i = 0; i < overlayOpacityAct.count(); i++) {
overlaySubMenu.addAction(overlayOpacityAct.at(i)); overlaySubMenu.addAction(overlayOpacityAct.at(i));
} }
contextMenu.addMenu(&overlaySubMenu); contextMenu.addMenu(&overlaySubMenu);
contextMenu.addSeparator();
contextMenu.addAction(closeAct2); // accept the event
event->accept();
contextMenu.exec(event->globalPos()); // popup the menu // popup the menu
contextMenu.exec(event->globalPos());
// ****************
} }
void OPMapGadgetWidget::closeEvent(QCloseEvent *event) void OPMapGadgetWidget::closeEvent(QCloseEvent *event)
@ -1300,12 +1309,6 @@ void OPMapGadgetWidget::createActions()
// *********************** // ***********************
// create menu actions // create menu actions
closeAct1 = new QAction(tr("Close menu"), this);
closeAct1->setStatusTip(tr("Close the context menu"));
closeAct2 = new QAction(tr("Close menu"), this);
closeAct2->setStatusTip(tr("Close the context menu"));
reloadAct = new QAction(tr("&Reload map"), this); reloadAct = new QAction(tr("&Reload map"), this);
reloadAct->setShortcut(tr("F5")); reloadAct->setShortcut(tr("F5"));
reloadAct->setStatusTip(tr("Reload the map tiles")); reloadAct->setStatusTip(tr("Reload the map tiles"));

View File

@ -236,8 +236,6 @@ private:
QPointer<ModelUavoProxy> UAVProxy; QPointer<ModelUavoProxy> UAVProxy;
QMutex m_map_mutex; QMutex m_map_mutex;
bool m_telemetry_connected; bool m_telemetry_connected;
QAction *closeAct1;
QAction *closeAct2;
QAction *reloadAct; QAction *reloadAct;
QAction *ripAct; QAction *ripAct;
QAction *copyMouseLatLonToClipAct; QAction *copyMouseLatLonToClipAct;
@ -310,7 +308,6 @@ private:
void setMapFollowingMode(); void setMapFollowingMode();
bool setHomeLocationObject(); bool setHomeLocationObject();
QMenu contextMenu;
internals::PointLatLng lastLatLngMouse; internals::PointLatLng lastLatLngMouse;
WayPointItem *magicWayPoint; WayPointItem *magicWayPoint;

View File

@ -1,22 +1,30 @@
TEMPLATE = lib TEMPLATE = lib
TARGET = ScopeGadget TARGET = ScopeGadget
DEFINES += SCOPE_LIBRARY DEFINES += SCOPE_LIBRARY
include(../../openpilotgcsplugin.pri) include(../../openpilotgcsplugin.pri)
include (scope_dependencies.pri) include (scope_dependencies.pri)
HEADERS += scopeplugin.h \
HEADERS += \
scopeplugin.h \
plotdata.h \ plotdata.h \
scope_global.h scope_global.h \
HEADERS += scopegadgetoptionspage.h scopegadgetoptionspage.h \
HEADERS += scopegadgetconfiguration.h scopegadgetconfiguration.h \
HEADERS += scopegadget.h scopegadget.h \
HEADERS += scopegadgetwidget.h scopegadgetwidget.h \
HEADERS += scopegadgetfactory.h scopegadgetfactory.h
SOURCES += scopeplugin.cpp \
plotdata.cpp SOURCES += \
SOURCES += scopegadgetoptionspage.cpp scopeplugin.cpp \
SOURCES += scopegadgetconfiguration.cpp plotdata.cpp \
SOURCES += scopegadget.cpp scopegadgetoptionspage.cpp \
SOURCES += scopegadgetfactory.cpp scopegadgetconfiguration.cpp \
SOURCES += scopegadgetwidget.cpp scopegadget.cpp \
scopegadgetfactory.cpp \
scopegadgetwidget.cpp
OTHER_FILES += ScopeGadget.pluginspec OTHER_FILES += ScopeGadget.pluginspec
FORMS += scopegadgetoptionspage.ui FORMS += scopegadgetoptionspage.ui

View File

@ -25,7 +25,6 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "scopeplugin.h"
#include "scopegadget.h" #include "scopegadget.h"
#include "scopegadgetconfiguration.h" #include "scopegadgetconfiguration.h"
#include "scopegadgetwidget.h" #include "scopegadgetwidget.h"
@ -33,9 +32,7 @@
#include <qcolor.h> #include <qcolor.h>
ScopeGadget::ScopeGadget(QString classId, ScopeGadgetWidget *widget, QWidget *parent) : ScopeGadget::ScopeGadget(QString classId, ScopeGadgetWidget *widget, QWidget *parent) :
IUAVGadget(classId, parent), IUAVGadget(classId, parent), m_widget(widget)
m_widget(widget),
configLoaded(false)
{} {}
void ScopeGadget::loadConfiguration(IUAVGadgetConfiguration *config) void ScopeGadget::loadConfiguration(IUAVGadgetConfiguration *config)
@ -86,10 +83,19 @@ void ScopeGadget::loadConfiguration(IUAVGadgetConfiguration *config)
} }
/** /**
Scope gadget destructor: should delete the associated Scope gadget destructor: should delete the associated scope gadget widget too!
scope gadget widget too!
*/ */
ScopeGadget::~ScopeGadget() ScopeGadget::~ScopeGadget()
{ {
delete m_widget; delete m_widget;
} }
void ScopeGadget::saveState(QSettings *qSettings)
{
m_widget->saveState(qSettings);
}
void ScopeGadget::restoreState(QSettings *qSettings)
{
m_widget->restoreState(qSettings);
}

View File

@ -32,10 +32,10 @@
#include <coreplugin/iuavgadget.h> #include <coreplugin/iuavgadget.h>
#include "scopegadgetwidget.h" #include "scopegadgetwidget.h"
class IUAVGadget;
// class QList<int>;
class QWidget; class QWidget;
class QString; class QString;
class QSettings;
class IUAVGadget;
class ScopeGadgetWidget; class ScopeGadgetWidget;
using namespace Core; using namespace Core;
@ -52,20 +52,23 @@ public:
{ {
return m_context; return m_context;
} }
QWidget *widget() QWidget *widget()
{ {
return m_widget; return m_widget;
} }
QString contextHelpId() const QString contextHelpId() const
{ {
return QString(); return QString();
} }
void saveState(QSettings *qSettings);
void restoreState(QSettings *qSettings);
private: private:
ScopeGadgetWidget *m_widget; ScopeGadgetWidget *m_widget;
QList<int> m_context; QList<int> m_context;
bool configLoaded;
}; };

View File

@ -25,8 +25,6 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <QDir>
#include "scopegadgetwidget.h" #include "scopegadgetwidget.h"
#include "utils/stylehelper.h" #include "utils/stylehelper.h"
@ -44,6 +42,7 @@
#include <iostream> #include <iostream>
#include <math.h> #include <math.h>
#include <QDebug> #include <QDebug>
#include <QDir>
#include <QColor> #include <QColor>
#include <QStringList> #include <QStringList>
#include <QWidget> #include <QWidget>
@ -52,14 +51,10 @@
#include <QMutexLocker> #include <QMutexLocker>
#include <QWheelEvent> #include <QWheelEvent>
// using namespace Core;
// ******************************************************************
ScopeGadgetWidget::ScopeGadgetWidget(QWidget *parent) : QwtPlot(parent) ScopeGadgetWidget::ScopeGadgetWidget(QWidget *parent) : QwtPlot(parent)
{ {
setMouseTracking(true); setMouseTracking(true);
// canvas()->setMouseTracking(true); // canvas()->setMouseTracking(true);
// Setup the timer that replots data // Setup the timer that replots data
replotTimer = new QTimer(this); replotTimer = new QTimer(this);
@ -109,8 +104,6 @@ ScopeGadgetWidget::~ScopeGadgetWidget()
clearCurvePlots(); clearCurvePlots();
} }
// ******************************************************************
void ScopeGadgetWidget::mousePressEvent(QMouseEvent *e) void ScopeGadgetWidget::mousePressEvent(QMouseEvent *e)
{ {
QwtPlot::mousePressEvent(e); QwtPlot::mousePressEvent(e);
@ -214,7 +207,6 @@ void ScopeGadgetWidget::deleteLegend()
disconnect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)), this, 0); disconnect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)), this, 0);
insertLegend(NULL, QwtPlot::TopLegend); insertLegend(NULL, QwtPlot::TopLegend);
// insertLegend(NULL, QwtPlot::ExternalLegend);
} }
void ScopeGadgetWidget::addLegend() void ScopeGadgetWidget::addLegend()
@ -227,27 +219,19 @@ void ScopeGadgetWidget::addLegend()
QwtLegend *legend = new QwtLegend(); QwtLegend *legend = new QwtLegend();
legend->setItemMode(QwtLegend::CheckableItem); legend->setItemMode(QwtLegend::CheckableItem);
legend->setFrameStyle(QFrame::Box | QFrame::Sunken); legend->setFrameStyle(QFrame::Box | QFrame::Sunken);
legend->setToolTip(tr("Click legend to show/hide scope trace")); legend->setToolTip(tr("Click legend to show/hide scope trace.\nDouble click legend or plot to show/hide legend."));
// set colors
QPalette pal = legend->palette(); QPalette pal = legend->palette();
pal.setColor(legend->backgroundRole(), QColor(100, 100, 100)); // background colour pal.setColor(legend->backgroundRole(), QColor(100, 100, 100));
// pal.setColor(legend->backgroundRole(), Qt::transparent); // background colour pal.setColor(QPalette::Text, QColor(0, 0, 0));
// pal.setColor(QPalette::Text, QColor(255, 255, 255)); // text colour
pal.setColor(QPalette::Text, QColor(0, 0, 0)); // text colour
legend->setPalette(pal); legend->setPalette(pal);
insertLegend(legend, QwtPlot::TopLegend); insertLegend(legend, QwtPlot::TopLegend);
// insertLegend(legend, QwtPlot::ExternalLegend);
//// Show a legend at the bottom
// QwtLegend *legend = new QwtLegend();
// legend->setItemMode(QwtLegend::CheckableItem);
// legend->setFrameStyle(QFrame::Box | QFrame::Sunken);
// insertLegend(legend, QwtPlot::BottomLegend);
// Update the checked/unchecked state of the legend items // Update the checked/unchecked state of the legend items
// -> this is necessary when hiding a legend where some plots are // -> this is necessary when hiding a legend where some plots are
// not visible, and the un-hiding it. // not visible, and then un-hiding it.
foreach(QwtPlotItem * item, this->itemList()) { foreach(QwtPlotItem * item, this->itemList()) {
bool on = item->isVisible(); bool on = item->isVisible();
QWidget *w = legend->find(item); QWidget *w = legend->find(item);
@ -269,15 +253,6 @@ void ScopeGadgetWidget::preparePlot(PlotType plotType)
setMinimumSize(64, 64); setMinimumSize(64, 64);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
// setMargin(1);
// QPalette pal = palette();
// QPalette::ColorRole cr = backgroundRole();
// pal.setColor(cr, QColor(128, 128, 128)); // background colour
// pal.setColor(QPalette::Text, QColor(255, 255, 255)); // text colour
// setPalette(pal);
// setCanvasBackground(Utils::StyleHelper::baseColor());
setCanvasBackground(QColor(64, 64, 64)); setCanvasBackground(QColor(64, 64, 64));
// Add grid lines // Add grid lines
@ -287,9 +262,6 @@ void ScopeGadgetWidget::preparePlot(PlotType plotType)
grid->setPen(QPen(Qt::darkGray, 1, Qt::DotLine)); grid->setPen(QPen(Qt::darkGray, 1, Qt::DotLine));
grid->attach(this); grid->attach(this);
// Add the legend
addLegend();
// Only start the timer if we are already connected // Only start the timer if we are already connected
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
if (cm->getCurrentConnection() && replotTimer) { if (cm->getCurrentConnection() && replotTimer) {
@ -304,9 +276,11 @@ void ScopeGadgetWidget::preparePlot(PlotType plotType)
void ScopeGadgetWidget::showCurve(QwtPlotItem *item, bool on) void ScopeGadgetWidget::showCurve(QwtPlotItem *item, bool on)
{ {
item->setVisible(!on); item->setVisible(!on);
QWidget *w = legend()->find(item); if (legend()) {
if (w && w->inherits("QwtLegendItem")) { QWidget *w = legend()->find(item);
((QwtLegendItem *)w)->setChecked(on); if (w && w->inherits("QwtLegendItem")) {
((QwtLegendItem *)w)->setChecked(on);
}
} }
mutex.lock(); mutex.lock();
@ -540,6 +514,42 @@ void ScopeGadgetWidget::clearCurvePlots()
m_curvesData.clear(); m_curvesData.clear();
} }
void ScopeGadgetWidget::saveState(QSettings *qSettings)
{
// plot state
int i = 1;
foreach(PlotData * plotData, m_curvesData.values()) {
bool plotVisible = plotData->curve->isVisible();
if (!plotVisible) {
qSettings->setValue(QString("plot%1").arg(i), plotVisible);
}
i++;
}
// legend state
qSettings->setValue("legendVisible", legend() != NULL);
}
void ScopeGadgetWidget::restoreState(QSettings *qSettings)
{
// plot state
int i = 1;
foreach(PlotData * plotData, m_curvesData.values()) {
bool visible = qSettings->value(QString("plot%1").arg(i), true).toBool();
showCurve(plotData->curve, !visible);
i++;
}
// legend state
bool legendVisible = qSettings->value("legendVisible", true).toBool();
if (legendVisible) {
addLegend();
} else {
deleteLegend();
}
}
/* /*
int csvLoggingEnable; int csvLoggingEnable;
@ -697,6 +707,7 @@ void ScopeGadgetWidget::csvLoggingConnect()
csvLoggingStart(); csvLoggingStart();
} }
} }
void ScopeGadgetWidget::csvLoggingDisconnect() void ScopeGadgetWidget::csvLoggingDisconnect()
{ {
m_csvLoggingHeaderSaved = 0; m_csvLoggingHeaderSaved = 0;

View File

@ -41,6 +41,8 @@
#include <QVector> #include <QVector>
#include <QMutex> #include <QMutex>
class QSettings;
/*! /*!
\brief This class is used to render the time values on the horizontal axis for the \brief This class is used to render the time values on the horizontal axis for the
ChronoPlot. ChronoPlot.
@ -95,9 +97,14 @@ public:
void addCurvePlot(QString uavObject, QString uavFieldSubField, int scaleOrderFactor = 0, int meanSamples = 1, void addCurvePlot(QString uavObject, QString uavFieldSubField, int scaleOrderFactor = 0, int meanSamples = 1,
QString mathFunction = "None", QPen pen = QPen(Qt::black), bool antialiased = true); QString mathFunction = "None", QPen pen = QPen(Qt::black), bool antialiased = true);
void clearCurvePlots(); void clearCurvePlots();
void saveState(QSettings *qSettings);
void restoreState(QSettings *qSettings);
int csvLoggingStart(); int csvLoggingStart();
int csvLoggingStop(); int csvLoggingStop();
void csvLoggingSetName(QString); void csvLoggingSetName(QString);
void setLoggingEnabled(bool value) void setLoggingEnabled(bool value)
{ {
m_csvLoggingEnabled = value; m_csvLoggingEnabled = value;