mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-29 07:24:13 +01:00
Merge branch 'next' into theothercliff/OP-1259_Cruise_Control_Tweaks
This commit is contained in:
commit
45fa3220a5
25
Makefile
25
Makefile
@ -450,11 +450,25 @@ else
|
||||
GCS_SILENT := silent
|
||||
endif
|
||||
|
||||
.NOTPARALLEL:
|
||||
.PHONY: openpilotgcs
|
||||
openpilotgcs: uavobjects_gcs
|
||||
$(V1) $(MKDIR) -p $(BUILD_DIR)/$@_$(GCS_BUILD_CONF)
|
||||
$(V1) ( cd $(BUILD_DIR)/$@_$(GCS_BUILD_CONF) && \
|
||||
$(QMAKE) $(ROOT_DIR)/ground/openpilotgcs/openpilotgcs.pro -spec $(QT_SPEC) -r CONFIG+="$(GCS_BUILD_CONF) $(GCS_SILENT)" $(GCS_QMAKE_OPTS) && \
|
||||
openpilotgcs: uavobjects_gcs openpilotgcs_qmake openpilotgcs_make
|
||||
|
||||
.PHONY: openpilotgcs_qmake
|
||||
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 ; \
|
||||
)
|
||||
|
||||
@ -947,6 +961,9 @@ help:
|
||||
@$(ECHO)
|
||||
@$(ECHO) " [GCS]"
|
||||
@$(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) " Supported build configurations: GCS_BUILD_CONF=debug|release (default is $(GCS_BUILD_CONF))"
|
||||
@$(ECHO)
|
||||
|
@ -63,8 +63,6 @@
|
||||
// Private types
|
||||
|
||||
// Private variables
|
||||
static uint32_t idleCounter;
|
||||
static uint32_t idleCounterClear;
|
||||
static xTaskHandle systemTaskHandle;
|
||||
static bool stackOverflow;
|
||||
static bool mallocFailed;
|
||||
@ -130,8 +128,6 @@ static void systemTask(__attribute__((unused)) void *parameters)
|
||||
}
|
||||
|
||||
// Initialize vars
|
||||
idleCounter = 0;
|
||||
idleCounterClear = 0;
|
||||
lastSysTime = xTaskGetTickCount();
|
||||
|
||||
// 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.
|
||||
*/
|
||||
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.
|
||||
|
@ -92,8 +92,6 @@
|
||||
// Private types
|
||||
|
||||
// Private variables
|
||||
static uint32_t idleCounter;
|
||||
static uint32_t idleCounterClear;
|
||||
static xTaskHandle systemTaskHandle;
|
||||
static xQueueHandle objectPersistenceQueue;
|
||||
static enum { STACKOVERFLOW_NONE = 0, STACKOVERFLOW_WARNING = 1, STACKOVERFLOW_CRITICAL = 3 } stackOverflow;
|
||||
@ -132,6 +130,7 @@ int32_t SystemModStart(void)
|
||||
// Register task
|
||||
PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_SYSTEM, systemTaskHandle);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -186,15 +185,12 @@ static void systemTask(__attribute__((unused)) void *parameters)
|
||||
*/
|
||||
PIOS_SYS_Reset();
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_IAP)
|
||||
/* Record a successful boot */
|
||||
PIOS_IAP_WriteBootCount(0);
|
||||
#endif
|
||||
|
||||
// Initialize vars
|
||||
idleCounter = 0;
|
||||
idleCounterClear = 0;
|
||||
|
||||
// Listen for SettingPersistance object updates, connect a callback function
|
||||
ObjectPersistenceConnectQueue(objectPersistenceQueue);
|
||||
@ -212,9 +208,10 @@ static void systemTask(__attribute__((unused)) void *parameters)
|
||||
// Main system loop
|
||||
while (1) {
|
||||
// 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
|
||||
updateSystemAlarms();
|
||||
#ifdef DIAG_I2C_WDG_STATS
|
||||
@ -227,10 +224,12 @@ static void systemTask(__attribute__((unused)) void *parameters)
|
||||
PIOS_TASK_MONITOR_ForEachTask(taskMonitorForEachCallback, &taskInfoData);
|
||||
TaskInfoSet(&taskInfoData);
|
||||
// Update the callback status object
|
||||
// if(FALSE){
|
||||
PIOS_CALLBACKSCHEDULER_ForEachCallback(callbackSchedulerForEachCallback, &callbackInfoData);
|
||||
CallbackInfoSet(&callbackInfoData);
|
||||
// }
|
||||
#endif
|
||||
|
||||
// }
|
||||
// Flash the heartbeat LED
|
||||
#if defined(PIOS_LED_HEARTBEAT)
|
||||
uint8_t armingStatus;
|
||||
@ -541,7 +540,6 @@ static uint16_t GetFreeIrqStackSize(void)
|
||||
*/
|
||||
static void updateStats()
|
||||
{
|
||||
static portTickType lastTickCount = 0;
|
||||
SystemStatsData stats;
|
||||
|
||||
// Get stats and update
|
||||
@ -559,10 +557,6 @@ static void updateStats()
|
||||
// Get Irq stack status
|
||||
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 (pios_uavo_settings_fs_id) {
|
||||
PIOS_FLASHFS_GetStats(pios_uavo_settings_fs_id, &fsStats);
|
||||
@ -575,16 +569,11 @@ static void updateStats()
|
||||
stats.UsrSlotsActive = fsStats.num_active_slots;
|
||||
}
|
||||
#endif
|
||||
portTickType now = xTaskGetTickCount();
|
||||
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;
|
||||
stats.CPULoad = 100 - PIOS_TASK_MONITOR_GetIdlePercentage();
|
||||
|
||||
#if defined(PIOS_INCLUDE_ADC) && defined(PIOS_ADC_USE_TEMP_SENSOR)
|
||||
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
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
|
@ -33,6 +33,7 @@
|
||||
static xSemaphoreHandle mLock;
|
||||
static xTaskHandle *mTaskHandles;
|
||||
static uint32_t mLastMonitorTime;
|
||||
static uint32_t mLastIdleMonitorTime;
|
||||
static uint16_t mMaxTasks;
|
||||
|
||||
/**
|
||||
@ -53,9 +54,11 @@ int32_t PIOS_TASK_MONITOR_Initialize(uint16_t max_tasks)
|
||||
|
||||
mMaxTasks = max_tasks;
|
||||
#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
|
||||
mLastMonitorTime = 0;
|
||||
mLastMonitorTime = 0;
|
||||
mLastIdleMonitorTime = 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -146,4 +149,31 @@ void PIOS_TASK_MONITOR_ForEachTask(TaskMonitorTaskInfoCallback callback, void *c
|
||||
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
|
||||
|
@ -104,4 +104,9 @@ typedef void (*TaskMonitorTaskInfoCallback)(uint16_t task_id, const struct pios_
|
||||
*/
|
||||
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
|
||||
|
@ -75,11 +75,9 @@
|
||||
#endif
|
||||
|
||||
/* Enable run time stats collection */
|
||||
#ifdef DIAG_TASKS
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
|
||||
#define configGENERATE_RUN_TIME_STATS 1
|
||||
#define INCLUDE_uxTaskGetRunTime 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() \
|
||||
do { \
|
||||
(*(unsigned long *)0xe000edfc) |= (1 << 24); /* DEMCR |= DEMCR_TRCENA */ \
|
||||
@ -87,6 +85,9 @@
|
||||
} \
|
||||
while (0)
|
||||
#define portGET_RUN_TIME_COUNTER_VALUE() (*(unsigned long *)0xe0001004) /* DWT_CYCCNT */
|
||||
|
||||
#ifdef DIAG_TASKS
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#else
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 1
|
||||
#endif
|
||||
|
@ -75,11 +75,9 @@
|
||||
#endif
|
||||
|
||||
/* Enable run time stats collection */
|
||||
#ifdef DIAG_TASKS
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
|
||||
#define configGENERATE_RUN_TIME_STATS 1
|
||||
#define INCLUDE_uxTaskGetRunTime 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() \
|
||||
do { \
|
||||
(*(unsigned long *)0xe000edfc) |= (1 << 24); /* DEMCR |= DEMCR_TRCENA */ \
|
||||
@ -87,6 +85,9 @@
|
||||
} \
|
||||
while (0)
|
||||
#define portGET_RUN_TIME_COUNTER_VALUE() (*(unsigned long *)0xe0001004) /* DWT_CYCCNT */
|
||||
|
||||
#ifdef DIAG_TASKS
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#else
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 1
|
||||
#endif
|
||||
|
@ -79,6 +79,7 @@
|
||||
/* Enable run time stats collection */
|
||||
#define configGENERATE_RUN_TIME_STATS 1
|
||||
#define INCLUDE_uxTaskGetRunTime 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||
|
||||
/*
|
||||
* Once we move to CMSIS2 we can at least use:
|
||||
|
@ -64,6 +64,7 @@
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||
|
||||
/* 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). */
|
||||
|
@ -79,6 +79,7 @@
|
||||
/* Enable run time stats collection */
|
||||
#define configGENERATE_RUN_TIME_STATS 1
|
||||
#define INCLUDE_uxTaskGetRunTime 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||
|
||||
/*
|
||||
* Once we move to CMSIS2 we can at least use:
|
||||
|
@ -13378,6 +13378,7 @@ border-radius: 5;</string>
|
||||
<property name="decimals">
|
||||
<number>5</number>
|
||||
|
||||
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.000100000000000</double>
|
||||
@ -15942,6 +15943,7 @@ border-radius: 5;</string>
|
||||
<string>element:Kp</string>
|
||||
<string>haslimits:no</string>
|
||||
<string>scale:1</string>
|
||||
|
||||
<string>buttongroup:5,20</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
@ -17353,6 +17355,7 @@ border-radius: 5;</string>
|
||||
<red>26</red>
|
||||
<green>26</green>
|
||||
<blue>26</blue>
|
||||
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
@ -24307,6 +24310,7 @@ border-radius: 5;</string>
|
||||
<string>buttongroup:16</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
|
@ -121,6 +121,10 @@ void UAVGadgetDecorator::saveState(QSettings *qSettings)
|
||||
if (m_activeConfiguration) {
|
||||
qSettings->setValue("activeConfiguration", m_activeConfiguration->name());
|
||||
}
|
||||
// save gadget individual state
|
||||
qSettings->beginGroup("state");
|
||||
m_gadget->saveState(qSettings);
|
||||
qSettings->endGroup();
|
||||
}
|
||||
|
||||
void UAVGadgetDecorator::restoreState(QSettings *qSettings)
|
||||
@ -134,4 +138,8 @@ void UAVGadgetDecorator::restoreState(QSettings *qSettings)
|
||||
break;
|
||||
}
|
||||
}
|
||||
// restore gadget individual state
|
||||
qSettings->beginGroup("state");
|
||||
m_gadget->restoreState(qSettings);
|
||||
qSettings->endGroup();
|
||||
}
|
||||
|
@ -131,7 +131,8 @@ struct hid_device_ {
|
||||
DWORD last_error_num;
|
||||
BOOL read_pending;
|
||||
char *read_buf;
|
||||
OVERLAPPED ol;
|
||||
OVERLAPPED rx_ol;
|
||||
OVERLAPPED tx_ol;
|
||||
};
|
||||
|
||||
static hid_device *new_hid_device()
|
||||
@ -145,15 +146,18 @@ static hid_device *new_hid_device()
|
||||
dev->last_error_num = 0;
|
||||
dev->read_pending = FALSE;
|
||||
dev->read_buf = NULL;
|
||||
memset(&dev->ol, 0, sizeof(dev->ol));
|
||||
dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*inital state f=nonsignaled*/, NULL);
|
||||
memset(&dev->rx_ol, 0, sizeof(dev->rx_ol));
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
LocalFree(dev->last_error_str);
|
||||
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;
|
||||
BOOL res;
|
||||
|
||||
OVERLAPPED ol;
|
||||
unsigned char *buf;
|
||||
memset(&ol, 0, sizeof(ol));
|
||||
|
||||
/* Make sure the right number of bytes are passed to WriteFile. Windows
|
||||
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;
|
||||
}
|
||||
|
||||
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 (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
|
||||
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) {
|
||||
/* The Write operation failed. */
|
||||
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;
|
||||
|
||||
/* Copy the handle for convenience. */
|
||||
HANDLE ev = dev->ol.hEvent;
|
||||
HANDLE ev = dev->rx_ol.hEvent;
|
||||
|
||||
if (!dev->read_pending) {
|
||||
/* Start an Overlapped I/O read. */
|
||||
dev->read_pending = TRUE;
|
||||
memset(dev->read_buf, 0, dev->input_report_length);
|
||||
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 (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
|
||||
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(). */
|
||||
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. */
|
||||
dev->read_pending = FALSE;
|
||||
|
@ -333,26 +333,30 @@ void OPMapGadgetWidget::wpDoubleClickEvent(WayPointItem *wp)
|
||||
}
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->reason() != QContextMenuEvent::Mouse) {
|
||||
return; // not a mouse click event
|
||||
// not a mouse click event
|
||||
return;
|
||||
}
|
||||
|
||||
// current mouse position
|
||||
QPoint p = m_map->mapFromGlobal(event->globalPos());
|
||||
m_context_menu_lat_lon = m_map->GetFromLocalToLatLng(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
|
||||
s = QString::number(m_context_menu_lat_lon.Lat(), 'f', 7) + " " + QString::number(m_context_menu_lat_lon.Lng(), 'f', 7);
|
||||
m_widget->labelMousePos->setText(s);
|
||||
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(mousePosString);
|
||||
|
||||
// find out if we have a waypoint under the mouse cursor
|
||||
QGraphicsItem *item = m_map->itemAt(p);
|
||||
@ -364,11 +368,9 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
waypoint_locked = (m_mouse_waypoint->flags() & QGraphicsItem::ItemIsMovable) == 0;
|
||||
}
|
||||
|
||||
// ****************
|
||||
// Dynamically create the popup menu
|
||||
QMenu contextMenu;
|
||||
|
||||
contextMenu.addAction(closeAct1);
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addAction(reloadAct);
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addAction(ripAct);
|
||||
@ -382,12 +384,20 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
|
||||
contextMenu.addSeparator();
|
||||
|
||||
QString mapMode;
|
||||
switch (m_map_mode) {
|
||||
case Normal_MapMode: s = tr(" (Normal)"); break;
|
||||
case MagicWaypoint_MapMode: s = tr(" (Magic Waypoint)"); break;
|
||||
default: s = tr(" (Unknown)"); break;
|
||||
case Normal_MapMode:
|
||||
mapMode = tr(" (Normal)");
|
||||
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);
|
||||
if (!act) {
|
||||
continue;
|
||||
@ -396,7 +406,7 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
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++) {
|
||||
mapModeSubMenu.addAction(mapModeAct.at(i));
|
||||
}
|
||||
@ -432,7 +442,8 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
|
||||
contextMenu.addAction(showUAVInfo);
|
||||
|
||||
contextMenu.addSeparator()->setText(tr("Zoom"));
|
||||
// Zoom section
|
||||
contextMenu.addSection(tr("Zoom"));
|
||||
|
||||
contextMenu.addAction(zoomInAct);
|
||||
contextMenu.addAction(zoomOutAct);
|
||||
@ -447,16 +458,16 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
|
||||
contextMenu.addAction(goMouseClickAct);
|
||||
|
||||
contextMenu.addSeparator()->setText(tr("HOME"));
|
||||
// Home section
|
||||
contextMenu.addSection(tr("Home"));
|
||||
|
||||
contextMenu.addAction(setHomeAct);
|
||||
contextMenu.addAction(showHomeAct);
|
||||
contextMenu.addAction(goHomeAct);
|
||||
|
||||
// ****
|
||||
// uav trails
|
||||
QMenu uav_menu(tr("UAV"));
|
||||
uav_menu.addSeparator()->setText(tr("UAV Trail"));
|
||||
uav_menu.addSection(tr("UAV Trail"));
|
||||
contextMenu.addMenu(&uav_menu);
|
||||
QMenu uavTrailTypeSubMenu(tr("UAV trail type") + " (" + mapcontrol::Helper::StrFromUAVTrailType(m_map->UAV->GetTrailType()) + ")", this);
|
||||
for (int i = 0; i < uavTrailTypeAct.count(); i++) {
|
||||
@ -482,22 +493,21 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
|
||||
uav_menu.addAction(clearUAVtrailAct);
|
||||
|
||||
// ****
|
||||
|
||||
uav_menu.addSeparator()->setText(tr("UAV"));
|
||||
// UAV section
|
||||
uav_menu.addSection(tr("UAV"));
|
||||
|
||||
uav_menu.addAction(showUAVAct);
|
||||
uav_menu.addAction(followUAVpositionAct);
|
||||
uav_menu.addAction(followUAVheadingAct);
|
||||
uav_menu.addAction(goUAVAct);
|
||||
|
||||
// *********
|
||||
// waypoint section
|
||||
#ifdef USE_PATHPLANNER
|
||||
switch (m_map_mode) {
|
||||
case Normal_MapMode:
|
||||
// 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(addWayPointActFromContextMenu);
|
||||
@ -515,30 +525,29 @@ void OPMapGadgetWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
}
|
||||
|
||||
if (m_map->WPPresent()) {
|
||||
contextMenu.addAction(clearWayPointsAct); // we have waypoints
|
||||
// we have waypoints
|
||||
contextMenu.addAction(clearWayPointsAct);
|
||||
}
|
||||
break;
|
||||
|
||||
case MagicWaypoint_MapMode:
|
||||
contextMenu.addSeparator()->setText(tr("Waypoints"));
|
||||
contextMenu.addSection(tr("Waypoints"));
|
||||
contextMenu.addAction(homeMagicWaypointAct);
|
||||
break;
|
||||
}
|
||||
#endif // ifdef USE_PATHPLANNER
|
||||
// *********
|
||||
|
||||
QMenu overlaySubMenu(tr("&Overlay Opacity "), this);
|
||||
for (int i = 0; i < overlayOpacityAct.count(); i++) {
|
||||
overlaySubMenu.addAction(overlayOpacityAct.at(i));
|
||||
}
|
||||
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)
|
||||
@ -1300,12 +1309,6 @@ void OPMapGadgetWidget::createActions()
|
||||
// ***********************
|
||||
// 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->setShortcut(tr("F5"));
|
||||
reloadAct->setStatusTip(tr("Reload the map tiles"));
|
||||
|
@ -236,8 +236,6 @@ private:
|
||||
QPointer<ModelUavoProxy> UAVProxy;
|
||||
QMutex m_map_mutex;
|
||||
bool m_telemetry_connected;
|
||||
QAction *closeAct1;
|
||||
QAction *closeAct2;
|
||||
QAction *reloadAct;
|
||||
QAction *ripAct;
|
||||
QAction *copyMouseLatLonToClipAct;
|
||||
@ -310,7 +308,6 @@ private:
|
||||
void setMapFollowingMode();
|
||||
|
||||
bool setHomeLocationObject();
|
||||
QMenu contextMenu;
|
||||
internals::PointLatLng lastLatLngMouse;
|
||||
WayPointItem *magicWayPoint;
|
||||
|
||||
|
@ -1,22 +1,30 @@
|
||||
TEMPLATE = lib
|
||||
TARGET = ScopeGadget
|
||||
|
||||
DEFINES += SCOPE_LIBRARY
|
||||
|
||||
include(../../openpilotgcsplugin.pri)
|
||||
include (scope_dependencies.pri)
|
||||
HEADERS += scopeplugin.h \
|
||||
|
||||
HEADERS += \
|
||||
scopeplugin.h \
|
||||
plotdata.h \
|
||||
scope_global.h
|
||||
HEADERS += scopegadgetoptionspage.h
|
||||
HEADERS += scopegadgetconfiguration.h
|
||||
HEADERS += scopegadget.h
|
||||
HEADERS += scopegadgetwidget.h
|
||||
HEADERS += scopegadgetfactory.h
|
||||
SOURCES += scopeplugin.cpp \
|
||||
plotdata.cpp
|
||||
SOURCES += scopegadgetoptionspage.cpp
|
||||
SOURCES += scopegadgetconfiguration.cpp
|
||||
SOURCES += scopegadget.cpp
|
||||
SOURCES += scopegadgetfactory.cpp
|
||||
SOURCES += scopegadgetwidget.cpp
|
||||
scope_global.h \
|
||||
scopegadgetoptionspage.h \
|
||||
scopegadgetconfiguration.h \
|
||||
scopegadget.h \
|
||||
scopegadgetwidget.h \
|
||||
scopegadgetfactory.h
|
||||
|
||||
SOURCES += \
|
||||
scopeplugin.cpp \
|
||||
plotdata.cpp \
|
||||
scopegadgetoptionspage.cpp \
|
||||
scopegadgetconfiguration.cpp \
|
||||
scopegadget.cpp \
|
||||
scopegadgetfactory.cpp \
|
||||
scopegadgetwidget.cpp
|
||||
|
||||
OTHER_FILES += ScopeGadget.pluginspec
|
||||
|
||||
FORMS += scopegadgetoptionspage.ui
|
||||
|
@ -25,7 +25,6 @@
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "scopeplugin.h"
|
||||
#include "scopegadget.h"
|
||||
#include "scopegadgetconfiguration.h"
|
||||
#include "scopegadgetwidget.h"
|
||||
@ -33,9 +32,7 @@
|
||||
#include <qcolor.h>
|
||||
|
||||
ScopeGadget::ScopeGadget(QString classId, ScopeGadgetWidget *widget, QWidget *parent) :
|
||||
IUAVGadget(classId, parent),
|
||||
m_widget(widget),
|
||||
configLoaded(false)
|
||||
IUAVGadget(classId, parent), m_widget(widget)
|
||||
{}
|
||||
|
||||
void ScopeGadget::loadConfiguration(IUAVGadgetConfiguration *config)
|
||||
@ -86,10 +83,19 @@ void ScopeGadget::loadConfiguration(IUAVGadgetConfiguration *config)
|
||||
}
|
||||
|
||||
/**
|
||||
Scope gadget destructor: should delete the associated
|
||||
scope gadget widget too!
|
||||
Scope gadget destructor: should delete the associated scope gadget widget too!
|
||||
*/
|
||||
ScopeGadget::~ScopeGadget()
|
||||
{
|
||||
delete m_widget;
|
||||
}
|
||||
|
||||
void ScopeGadget::saveState(QSettings *qSettings)
|
||||
{
|
||||
m_widget->saveState(qSettings);
|
||||
}
|
||||
|
||||
void ScopeGadget::restoreState(QSettings *qSettings)
|
||||
{
|
||||
m_widget->restoreState(qSettings);
|
||||
}
|
||||
|
@ -32,10 +32,10 @@
|
||||
#include <coreplugin/iuavgadget.h>
|
||||
#include "scopegadgetwidget.h"
|
||||
|
||||
class IUAVGadget;
|
||||
// class QList<int>;
|
||||
class QWidget;
|
||||
class QString;
|
||||
class QSettings;
|
||||
class IUAVGadget;
|
||||
class ScopeGadgetWidget;
|
||||
|
||||
using namespace Core;
|
||||
@ -52,20 +52,23 @@ public:
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
QWidget *widget()
|
||||
{
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
QString contextHelpId() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
void saveState(QSettings *qSettings);
|
||||
void restoreState(QSettings *qSettings);
|
||||
|
||||
private:
|
||||
ScopeGadgetWidget *m_widget;
|
||||
QList<int> m_context;
|
||||
|
||||
bool configLoaded;
|
||||
};
|
||||
|
||||
|
||||
|
@ -25,8 +25,6 @@
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <QDir>
|
||||
#include "scopegadgetwidget.h"
|
||||
#include "utils/stylehelper.h"
|
||||
|
||||
@ -44,6 +42,7 @@
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QColor>
|
||||
#include <QStringList>
|
||||
#include <QWidget>
|
||||
@ -52,14 +51,10 @@
|
||||
#include <QMutexLocker>
|
||||
#include <QWheelEvent>
|
||||
|
||||
// using namespace Core;
|
||||
|
||||
// ******************************************************************
|
||||
|
||||
ScopeGadgetWidget::ScopeGadgetWidget(QWidget *parent) : QwtPlot(parent)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
// canvas()->setMouseTracking(true);
|
||||
// canvas()->setMouseTracking(true);
|
||||
|
||||
// Setup the timer that replots data
|
||||
replotTimer = new QTimer(this);
|
||||
@ -109,8 +104,6 @@ ScopeGadgetWidget::~ScopeGadgetWidget()
|
||||
clearCurvePlots();
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
||||
void ScopeGadgetWidget::mousePressEvent(QMouseEvent *e)
|
||||
{
|
||||
QwtPlot::mousePressEvent(e);
|
||||
@ -214,7 +207,6 @@ void ScopeGadgetWidget::deleteLegend()
|
||||
disconnect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)), this, 0);
|
||||
|
||||
insertLegend(NULL, QwtPlot::TopLegend);
|
||||
// insertLegend(NULL, QwtPlot::ExternalLegend);
|
||||
}
|
||||
|
||||
void ScopeGadgetWidget::addLegend()
|
||||
@ -227,27 +219,19 @@ void ScopeGadgetWidget::addLegend()
|
||||
QwtLegend *legend = new QwtLegend();
|
||||
legend->setItemMode(QwtLegend::CheckableItem);
|
||||
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();
|
||||
pal.setColor(legend->backgroundRole(), QColor(100, 100, 100)); // background colour
|
||||
// pal.setColor(legend->backgroundRole(), Qt::transparent); // background colour
|
||||
// pal.setColor(QPalette::Text, QColor(255, 255, 255)); // text colour
|
||||
pal.setColor(QPalette::Text, QColor(0, 0, 0)); // text colour
|
||||
pal.setColor(legend->backgroundRole(), QColor(100, 100, 100));
|
||||
pal.setColor(QPalette::Text, QColor(0, 0, 0));
|
||||
legend->setPalette(pal);
|
||||
|
||||
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
|
||||
// -> 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()) {
|
||||
bool on = item->isVisible();
|
||||
QWidget *w = legend->find(item);
|
||||
@ -269,15 +253,6 @@ void ScopeGadgetWidget::preparePlot(PlotType plotType)
|
||||
setMinimumSize(64, 64);
|
||||
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));
|
||||
|
||||
// Add grid lines
|
||||
@ -287,9 +262,6 @@ void ScopeGadgetWidget::preparePlot(PlotType plotType)
|
||||
grid->setPen(QPen(Qt::darkGray, 1, Qt::DotLine));
|
||||
grid->attach(this);
|
||||
|
||||
// Add the legend
|
||||
addLegend();
|
||||
|
||||
// Only start the timer if we are already connected
|
||||
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
|
||||
if (cm->getCurrentConnection() && replotTimer) {
|
||||
@ -304,9 +276,11 @@ void ScopeGadgetWidget::preparePlot(PlotType plotType)
|
||||
void ScopeGadgetWidget::showCurve(QwtPlotItem *item, bool on)
|
||||
{
|
||||
item->setVisible(!on);
|
||||
QWidget *w = legend()->find(item);
|
||||
if (w && w->inherits("QwtLegendItem")) {
|
||||
((QwtLegendItem *)w)->setChecked(on);
|
||||
if (legend()) {
|
||||
QWidget *w = legend()->find(item);
|
||||
if (w && w->inherits("QwtLegendItem")) {
|
||||
((QwtLegendItem *)w)->setChecked(on);
|
||||
}
|
||||
}
|
||||
|
||||
mutex.lock();
|
||||
@ -540,6 +514,42 @@ void ScopeGadgetWidget::clearCurvePlots()
|
||||
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;
|
||||
@ -697,6 +707,7 @@ void ScopeGadgetWidget::csvLoggingConnect()
|
||||
csvLoggingStart();
|
||||
}
|
||||
}
|
||||
|
||||
void ScopeGadgetWidget::csvLoggingDisconnect()
|
||||
{
|
||||
m_csvLoggingHeaderSaved = 0;
|
||||
|
@ -41,6 +41,8 @@
|
||||
#include <QVector>
|
||||
#include <QMutex>
|
||||
|
||||
class QSettings;
|
||||
|
||||
/*!
|
||||
\brief This class is used to render the time values on the horizontal axis for the
|
||||
ChronoPlot.
|
||||
@ -95,9 +97,14 @@ public:
|
||||
void addCurvePlot(QString uavObject, QString uavFieldSubField, int scaleOrderFactor = 0, int meanSamples = 1,
|
||||
QString mathFunction = "None", QPen pen = QPen(Qt::black), bool antialiased = true);
|
||||
void clearCurvePlots();
|
||||
|
||||
void saveState(QSettings *qSettings);
|
||||
void restoreState(QSettings *qSettings);
|
||||
|
||||
int csvLoggingStart();
|
||||
int csvLoggingStop();
|
||||
void csvLoggingSetName(QString);
|
||||
|
||||
void setLoggingEnabled(bool value)
|
||||
{
|
||||
m_csvLoggingEnabled = value;
|
||||
|
Loading…
Reference in New Issue
Block a user