mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-30 08:24:11 +01:00
Merge remote-tracking branch 'origin/next' into laurent/OP-1337_French_translations_updates
This commit is contained in:
commit
2f3cca7478
3
.gitignore
vendored
3
.gitignore
vendored
@ -24,6 +24,9 @@ core
|
||||
|
||||
# ground
|
||||
openpilotgcs-build-desktop
|
||||
ground/openpilotgcs/.cproject
|
||||
ground/openpilotgcs/.project
|
||||
ground/openpilotgcs/.settings
|
||||
|
||||
# Ignore some of the .pro.user files
|
||||
*.pro.user
|
||||
|
2
Makefile
2
Makefile
@ -747,7 +747,7 @@ ifneq ($(strip $(filter package clean_package,$(MAKECMDGOALS))),)
|
||||
|
||||
# Packaged GCS should depend on opfw_resource
|
||||
ifneq ($(strip $(filter package clean_package,$(MAKECMDGOALS))),)
|
||||
$(eval openpilotgcs: $(OPFW_RESOURCE))
|
||||
$(eval openpilotgcs_qmake: $(OPFW_RESOURCE))
|
||||
endif
|
||||
|
||||
# Clean the build directory if clean_package is requested
|
||||
|
@ -254,6 +254,33 @@ static int32_t hasSeverity(SystemAlarmsAlarmOptions severity)
|
||||
xSemaphoreGiveRecursive(lock);
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Get the highest alarm severity
|
||||
* @return
|
||||
*/
|
||||
SystemAlarmsAlarmOptions AlarmsGetHighestSeverity()
|
||||
{
|
||||
SystemAlarmsAlarmData alarmsData;
|
||||
SystemAlarmsAlarmOptions highest = SYSTEMALARMS_ALARM_UNINITIALISED;
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(lock, portMAX_DELAY);
|
||||
|
||||
// Read alarms
|
||||
SystemAlarmsAlarmGet(&alarmsData);
|
||||
|
||||
// Go through alarms and find the highest severity
|
||||
uint32_t n = 0;
|
||||
while (n < SYSTEMALARMS_ALARM_NUMELEM && highest != SYSTEMALARMS_ALARM_CRITICAL) {
|
||||
if (cast_struct_to_array(alarmsData, alarmsData.Actuator)[n] > highest) {
|
||||
highest = cast_struct_to_array(alarmsData, alarmsData.Actuator)[n];
|
||||
}
|
||||
n++;
|
||||
}
|
||||
|
||||
xSemaphoreGiveRecursive(lock);
|
||||
return highest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
@ -42,9 +42,11 @@ int32_t AlarmsDefault(SystemAlarmsAlarmElem alarm);
|
||||
void AlarmsDefaultAll();
|
||||
int32_t AlarmsClear(SystemAlarmsAlarmElem alarm);
|
||||
void AlarmsClearAll();
|
||||
|
||||
int32_t AlarmsHasWarnings();
|
||||
int32_t AlarmsHasErrors();
|
||||
int32_t AlarmsHasCritical();
|
||||
SystemAlarmsAlarmOptions AlarmsGetHighestSeverity();
|
||||
|
||||
#endif // ALARMS_H
|
||||
|
||||
|
38
flight/libraries/inc/notification.h
Normal file
38
flight/libraries/inc/notification.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file notification.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
|
||||
* @brief notification library
|
||||
* --
|
||||
* @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 NOTIFICATION_H
|
||||
#define NOTIFICATION_H
|
||||
|
||||
// period of each blink phase
|
||||
#define LED_BLINK_PERIOD_MS 200
|
||||
|
||||
// update the status snapshot used by notifcations
|
||||
void NotificationUpdateStatus();
|
||||
|
||||
// run the led notifications
|
||||
void NotificationOnboardLedsRun();
|
||||
|
||||
#endif /* NOTIFICATION_H */
|
296
flight/libraries/notification.c
Normal file
296
flight/libraries/notification.c
Normal file
@ -0,0 +1,296 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file notification.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
|
||||
* @brief notification library.
|
||||
* --
|
||||
* @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 "inc/notification.h"
|
||||
#include <openpilot.h>
|
||||
#include <pios_struct_helper.h>
|
||||
#include <systemalarms.h>
|
||||
#include <flightstatus.h>
|
||||
#include <pios_notify.h>
|
||||
|
||||
#ifdef PIOS_LED_ALARM
|
||||
#define ALARM_LED_ON() PIOS_LED_On(PIOS_LED_ALARM)
|
||||
#define ALARM_LED_OFF() PIOS_LED_Off(PIOS_LED_ALARM)
|
||||
#else
|
||||
#define ALARM_LED_ON()
|
||||
#define ALARM_LED_OFF()
|
||||
#endif
|
||||
|
||||
#ifdef PIOS_LED_HEARTBEAT
|
||||
#define HEARTBEAT_LED_ON() PIOS_LED_On(PIOS_LED_HEARTBEAT)
|
||||
#define HEARTBEAT_LED_OFF() PIOS_LED_Off(PIOS_LED_HEARTBEAT)
|
||||
#else
|
||||
#define HEARTBEAT_LED_ON()
|
||||
#define HEARTBEAT_LED_OFF()
|
||||
#endif
|
||||
|
||||
#define BLINK_R_ALARM_PATTERN(x) \
|
||||
(x == SYSTEMALARMS_ALARM_OK ? 0 : \
|
||||
x == SYSTEMALARMS_ALARM_WARNING ? 0b0000000001000000 : \
|
||||
x == SYSTEMALARMS_ALARM_ERROR ? 0b0000001000100000 : \
|
||||
x == SYSTEMALARMS_ALARM_CRITICAL ? 0b0111111111111110 : 0)
|
||||
#define BLINK_B_ALARM_PATTERN(x) \
|
||||
(x == SYSTEMALARMS_ALARM_OK ? 0 : \
|
||||
x == SYSTEMALARMS_ALARM_WARNING ? 0 : \
|
||||
x == SYSTEMALARMS_ALARM_ERROR ? 0 : \
|
||||
x == SYSTEMALARMS_ALARM_CRITICAL ? 0 : 0)
|
||||
|
||||
|
||||
#define BLINK_B_FM_ARMED_PATTERN(x) \
|
||||
(x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED1 ? 0b0000000000000001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED2 ? 0b0000000000100001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED3 ? 0b0000010000100001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED4 ? 0b0000000000000001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED5 ? 0b0000000000100001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED6 ? 0b0000010000100001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD ? 0b0000010000100001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_RETURNTOBASE ? 0b0001000100010001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_LAND ? 0b0001000100010001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_PATHPLANNER ? 0b0000010000100001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_POI ? 0b0000010000100001 : 0b0000000000000001)
|
||||
|
||||
#define BLINK_R_FM_ARMED_PATTERN(x) \
|
||||
(x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED1 ? 0b0000000000000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED2 ? 0b0000000000000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED3 ? 0b0000000000000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED4 ? 0b0000000000000001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED5 ? 0b0000000000000001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED6 ? 0b0000000000000001 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD ? 0b0000010000000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_RETURNTOBASE ? 0b0001000100000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_LAND ? 0b0001000100000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_PATHPLANNER ? 0b0000010000000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_POI ? 0b0000010000000000 : 0b0000010000000000)
|
||||
|
||||
#define BLINK_B_FM_DISARMED_PATTERN(x) \
|
||||
(x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED1 ? 0b0000000000000011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED2 ? 0b0000000001100011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED3 ? 0b0000110001100011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED4 ? 0b0000000000000011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED5 ? 0b0000000001100011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED6 ? 0b0000110001100011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD ? 0b0000110001100011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_RETURNTOBASE ? 0b0011001100110011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_LAND ? 0b0011001100110011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_PATHPLANNER ? 0b0000110001100011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_POI ? 0b0000110001100011 : 0b0000000000000011)
|
||||
|
||||
#define BLINK_R_FM_DISARMED_PATTERN(x) \
|
||||
(x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED1 ? 0b0000000000000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED2 ? 0b0000000000000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED3 ? 0b0000000000000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED4 ? 0b0000000000000011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED5 ? 0b0000000000000011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_STABILIZED6 ? 0b0000000000000011 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD ? 0b0000110000000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_RETURNTOBASE ? 0b0011001100000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_LAND ? 0b0011001100000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_PATHPLANNER ? 0b0000110000000000 : \
|
||||
x == FLIGHTSTATUS_FLIGHTMODE_POI ? 0b0000110000000000 : 0b0000110000000000)
|
||||
|
||||
#define BLINK_B_HEARTBEAT_PATTERN 0b0001111111111111
|
||||
#define BLINK_R_HEARTBEAT_PATTERN 0
|
||||
|
||||
#define BLINK_B_NOTIFY_PATTERN(x) \
|
||||
(x == NOTIFY_NONE ? 0 : \
|
||||
x == NOTIFY_OK ? 0b0000100100111111 : \
|
||||
x == NOTIFY_NOK ? 0b0000000000111111 : \
|
||||
x == NOTIFY_DRAW_ATTENTION ? 0b0101010101010101 : 0b0101010101010101)
|
||||
|
||||
#define BLINK_R_NOTIFY_PATTERN(x) \
|
||||
(x == NOTIFY_NONE ? 0 : \
|
||||
x == NOTIFY_OK ? 0b0000000000001111 : \
|
||||
x == NOTIFY_NOK ? 0b0011000011001111 : \
|
||||
x == NOTIFY_DRAW_ATTENTION ? 0b1010101010101010 : 0b1010101010101010)
|
||||
|
||||
// led notification handling
|
||||
static volatile SystemAlarmsAlarmOptions currentAlarmLevel = SYSTEMALARMS_ALARM_OK;
|
||||
static volatile FlightStatusData currentFlightStatus;
|
||||
static volatile bool started = false;
|
||||
static volatile pios_notify_notification nextNotification = NOTIFY_NONE;
|
||||
|
||||
#ifdef PIOS_LED_ALARM
|
||||
static bool handleAlarms(uint16_t *r_pattern, uint16_t *b_pattern);
|
||||
#endif // PIOS_LED_ALARM
|
||||
static bool handleNotifications(pios_notify_notification runningNotification, uint16_t *r_pattern, uint16_t *b_pattern);
|
||||
static void handleFlightMode(uint16_t *r_pattern, uint16_t *b_pattern);
|
||||
static void handleHeartbeat(uint16_t *r_pattern, uint16_t *b_pattern);
|
||||
void NotificationUpdateStatus()
|
||||
{
|
||||
started = true;
|
||||
// get values to be used for led handling
|
||||
FlightStatusGet((FlightStatusData *)¤tFlightStatus);
|
||||
currentAlarmLevel = AlarmsGetHighestSeverity();
|
||||
if (nextNotification == NOTIFY_NONE) {
|
||||
nextNotification = PIOS_NOTIFY_GetActiveNotification(true);
|
||||
}
|
||||
}
|
||||
|
||||
void NotificationOnboardLedsRun()
|
||||
{
|
||||
static portTickType lastRunTimestamp;
|
||||
static uint16_t r_pattern;
|
||||
static uint16_t b_pattern;
|
||||
static uint8_t cycleCount; // count the number of cycles
|
||||
static uint8_t lastFlightMode = -1;
|
||||
static bool forceShowFlightMode = false;
|
||||
static pios_notify_notification runningNotification = NOTIFY_NONE;
|
||||
static enum {
|
||||
STATUS_NOTIFY,
|
||||
STATUS_ALARM,
|
||||
STATUS_FLIGHTMODE, // flightMode/HeartBeat
|
||||
STATUS_LENGHT
|
||||
} status;
|
||||
|
||||
if (!started || (xTaskGetTickCount() - lastRunTimestamp) < (LED_BLINK_PERIOD_MS * portTICK_RATE_MS / 4)) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastRunTimestamp = xTaskGetTickCount();
|
||||
// the led will show various status information, subdivided in three phases
|
||||
// - Notification
|
||||
// - Alarm
|
||||
// - Flight status
|
||||
// they are shown using the above priority
|
||||
// a phase last exactly 8 cycles (so bit 1<<4 is used to determine if a phase end
|
||||
|
||||
cycleCount++;
|
||||
// Notifications are "modal" to other statuses so they takes precedence
|
||||
if (status != STATUS_NOTIFY && nextNotification != NOTIFY_NONE) {
|
||||
// read next notification to show
|
||||
runningNotification = nextNotification;
|
||||
nextNotification = NOTIFY_NONE;
|
||||
// Force a notification status
|
||||
status = STATUS_NOTIFY;
|
||||
cycleCount = 0; // instantly start a notify cycle
|
||||
} else {
|
||||
if (lastFlightMode != currentFlightStatus.FlightMode) {
|
||||
status = STATUS_FLIGHTMODE;
|
||||
lastFlightMode = currentFlightStatus.FlightMode;
|
||||
cycleCount = 0; // instantly start a flightMode cycle
|
||||
forceShowFlightMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
// check if a phase has just finished
|
||||
if (cycleCount & 0x10) {
|
||||
HEARTBEAT_LED_OFF();
|
||||
ALARM_LED_OFF();
|
||||
cycleCount = 0x0;
|
||||
forceShowFlightMode = false;
|
||||
// Notification has been just shown, cleanup
|
||||
if (status == STATUS_NOTIFY) {
|
||||
runningNotification = NOTIFY_NONE;
|
||||
}
|
||||
status = (status + 1) % STATUS_LENGHT;
|
||||
}
|
||||
|
||||
if (status == STATUS_NOTIFY) {
|
||||
if (!cycleCount && !handleNotifications(runningNotification, &r_pattern, &b_pattern)) {
|
||||
// no notifications, advance
|
||||
status++;
|
||||
}
|
||||
}
|
||||
|
||||
// Handles Alarm display
|
||||
if (status == STATUS_ALARM) {
|
||||
#ifdef PIOS_LED_ALARM
|
||||
if (!cycleCount && !handleAlarms(&r_pattern, &b_pattern)) {
|
||||
// no alarms, advance
|
||||
status++;
|
||||
}
|
||||
#else
|
||||
// no alarms leds, advance
|
||||
status++;
|
||||
#endif // PIOS_LED_ALARM
|
||||
}
|
||||
|
||||
// **** Handles flightmode display
|
||||
if (status == STATUS_FLIGHTMODE && !cycleCount) {
|
||||
if (forceShowFlightMode || currentFlightStatus.Armed != FLIGHTSTATUS_ARMED_DISARMED) {
|
||||
handleFlightMode(&r_pattern, &b_pattern);
|
||||
} else {
|
||||
handleHeartbeat(&r_pattern, &b_pattern);
|
||||
}
|
||||
}
|
||||
|
||||
// led output
|
||||
if (b_pattern & 0x1) {
|
||||
HEARTBEAT_LED_ON();
|
||||
} else {
|
||||
HEARTBEAT_LED_OFF();
|
||||
}
|
||||
if (r_pattern & 0x1) {
|
||||
ALARM_LED_ON();
|
||||
} else {
|
||||
ALARM_LED_OFF();
|
||||
}
|
||||
r_pattern >>= 1;
|
||||
b_pattern >>= 1;
|
||||
}
|
||||
|
||||
#if defined(PIOS_LED_ALARM)
|
||||
static bool handleAlarms(uint16_t *r_pattern, uint16_t *b_pattern)
|
||||
{
|
||||
if (currentAlarmLevel == SYSTEMALARMS_ALARM_OK) {
|
||||
return false;
|
||||
}
|
||||
*b_pattern = BLINK_B_ALARM_PATTERN(currentAlarmLevel);
|
||||
*r_pattern = BLINK_R_ALARM_PATTERN(currentAlarmLevel);
|
||||
return true;
|
||||
}
|
||||
#endif /* PIOS_LED_ALARM */
|
||||
|
||||
|
||||
static bool handleNotifications(pios_notify_notification runningNotification, uint16_t *r_pattern, uint16_t *b_pattern)
|
||||
{
|
||||
if (runningNotification == NOTIFY_NONE) {
|
||||
return false;
|
||||
}
|
||||
*b_pattern = BLINK_B_NOTIFY_PATTERN(runningNotification);
|
||||
*r_pattern = BLINK_R_NOTIFY_PATTERN(runningNotification);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void handleFlightMode(uint16_t *r_pattern, uint16_t *b_pattern)
|
||||
{
|
||||
// Flash the heartbeat LED
|
||||
uint8_t flightmode = currentFlightStatus.FlightMode;
|
||||
|
||||
if (currentFlightStatus.Armed == FLIGHTSTATUS_ARMED_DISARMED) {
|
||||
*b_pattern = BLINK_B_FM_DISARMED_PATTERN(flightmode);
|
||||
*r_pattern = BLINK_R_FM_DISARMED_PATTERN(flightmode);
|
||||
} else {
|
||||
*b_pattern = BLINK_B_FM_ARMED_PATTERN(flightmode);
|
||||
*r_pattern = BLINK_R_FM_ARMED_PATTERN(flightmode);
|
||||
}
|
||||
}
|
||||
|
||||
static void handleHeartbeat(uint16_t *r_pattern, uint16_t *b_pattern)
|
||||
{
|
||||
// Flash the heartbeat LED
|
||||
*b_pattern = BLINK_B_HEARTBEAT_PATTERN;
|
||||
*r_pattern = BLINK_R_HEARTBEAT_PATTERN;
|
||||
}
|
@ -60,7 +60,7 @@
|
||||
static xTaskHandle taskHandle;
|
||||
static bool airspeedEnabled = false;
|
||||
static AirspeedSettingsData airspeedSettings;
|
||||
static AirspeedSettingsAirspeedSensorTypeOptions lastAirspeedSensorType = 0;
|
||||
static AirspeedSettingsAirspeedSensorTypeOptions lastAirspeedSensorType = -1;
|
||||
static int8_t airspeedADCPin = -1;
|
||||
|
||||
|
||||
@ -119,8 +119,6 @@ int32_t AirspeedInitialize()
|
||||
}
|
||||
}
|
||||
|
||||
lastAirspeedSensorType = airspeedSettings.AirspeedSensorType;
|
||||
|
||||
AirspeedSensorInitialize();
|
||||
AirspeedSettingsInitialize();
|
||||
|
||||
@ -137,17 +135,14 @@ MODULE_INITCALL(AirspeedInitialize, AirspeedStart);
|
||||
static void airspeedTask(__attribute__((unused)) void *parameters)
|
||||
{
|
||||
AirspeedSettingsUpdatedCb(AirspeedSettingsHandle());
|
||||
|
||||
bool gpsAirspeedInitialized = false;
|
||||
AirspeedSensorData airspeedData;
|
||||
AirspeedSensorGet(&airspeedData);
|
||||
|
||||
AirspeedSettingsUpdatedCb(NULL);
|
||||
|
||||
gps_airspeedInitialize();
|
||||
|
||||
airspeedData.SensorConnected = AIRSPEEDSENSOR_SENSORCONNECTED_FALSE;
|
||||
|
||||
|
||||
// Main task loop
|
||||
portTickType lastSysTime = xTaskGetTickCount();
|
||||
while (1) {
|
||||
@ -160,8 +155,21 @@ static void airspeedTask(__attribute__((unused)) void *parameters)
|
||||
if (airspeedSettings.AirspeedSensorType != lastAirspeedSensorType) {
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_AIRSPEED, SYSTEMALARMS_ALARM_DEFAULT);
|
||||
lastAirspeedSensorType = airspeedSettings.AirspeedSensorType;
|
||||
switch (airspeedSettings.AirspeedSensorType) {
|
||||
case AIRSPEEDSETTINGS_AIRSPEEDSENSORTYPE_NONE:
|
||||
// AirspeedSensor will not be updated until a different sensor is selected
|
||||
// set the disconencted satus now
|
||||
airspeedData.SensorConnected = AIRSPEEDSENSOR_SENSORCONNECTED_FALSE;
|
||||
AirspeedSensorSet(&airspeedData);
|
||||
break;
|
||||
case AIRSPEEDSETTINGS_AIRSPEEDSENSORTYPE_GROUNDSPEEDBASEDWINDESTIMATION:
|
||||
if (!gpsAirspeedInitialized) {
|
||||
gpsAirspeedInitialized = true;
|
||||
gps_airspeedInitialize();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (airspeedSettings.AirspeedSensorType) {
|
||||
#if defined(PIOS_INCLUDE_MPXV)
|
||||
case AIRSPEEDSETTINGS_AIRSPEEDSENSORTYPE_DIYDRONESMPXV7002:
|
||||
@ -186,6 +194,10 @@ static void airspeedTask(__attribute__((unused)) void *parameters)
|
||||
gps_airspeedGet(&airspeedData, &airspeedSettings);
|
||||
break;
|
||||
case AIRSPEEDSETTINGS_AIRSPEEDSENSORTYPE_NONE:
|
||||
// no need to check so often until a sensor is enabled
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_AIRSPEED, SYSTEMALARMS_ALARM_DEFAULT);
|
||||
vTaskDelay(2000 / portTICK_RATE_MS);
|
||||
continue;
|
||||
default:
|
||||
airspeedData.SensorConnected = AIRSPEEDSENSOR_SENSORCONNECTED_FALSE;
|
||||
break;
|
||||
|
@ -63,7 +63,7 @@
|
||||
#include "taskinfo.h"
|
||||
|
||||
#include "CoordinateConversions.h"
|
||||
|
||||
#include <pios_notify.h>
|
||||
|
||||
// Private constants
|
||||
#define STACK_SIZE_BYTES 540
|
||||
@ -252,6 +252,7 @@ static void AttitudeTask(__attribute__((unused)) void *parameters)
|
||||
rollPitchBiasRate = 0.01f;
|
||||
accel_filter_enabled = false;
|
||||
init = 0;
|
||||
PIOS_NOTIFY_StartNotification(NOTIFY_DRAW_ATTENTION, NOTIFY_PRIORITY_REGULAR);
|
||||
} else if (zero_during_arming && (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMING)) {
|
||||
accelKp = 1.0f;
|
||||
accelKi = 0.0f;
|
||||
@ -259,6 +260,7 @@ static void AttitudeTask(__attribute__((unused)) void *parameters)
|
||||
rollPitchBiasRate = 0.01f;
|
||||
accel_filter_enabled = false;
|
||||
init = 0;
|
||||
PIOS_NOTIFY_StartNotification(NOTIFY_DRAW_ATTENTION, NOTIFY_PRIORITY_REGULAR);
|
||||
} else if (init == 0) {
|
||||
// Reload settings (all the rates)
|
||||
AttitudeSettingsAccelKiGet(&accelKi);
|
||||
|
@ -63,21 +63,24 @@ static float GravityAccel(float latitude, float longitude, float altitude);
|
||||
// ****************
|
||||
// Private constants
|
||||
|
||||
#define GPS_TIMEOUT_MS 500
|
||||
|
||||
#define GPS_TIMEOUT_MS 500
|
||||
// delay from detecting HomeLocation.Set == False before setting new homelocation
|
||||
// this prevent that a save with homelocation.Set = false triggered by gps ends saving
|
||||
// the new location with Set = true.
|
||||
#define GPS_HOMELOCATION_SET_DELAY 5000
|
||||
|
||||
#ifdef PIOS_GPS_SETS_HOMELOCATION
|
||||
// Unfortunately need a good size stack for the WMM calculation
|
||||
#define STACK_SIZE_BYTES 1024
|
||||
#define STACK_SIZE_BYTES 1024
|
||||
#else
|
||||
#if defined(PIOS_GPS_MINIMAL)
|
||||
#define STACK_SIZE_BYTES 500
|
||||
#define STACK_SIZE_BYTES 500
|
||||
#else
|
||||
#define STACK_SIZE_BYTES 650
|
||||
#define STACK_SIZE_BYTES 650
|
||||
#endif // PIOS_GPS_MINIMAL
|
||||
#endif // PIOS_GPS_SETS_HOMELOCATION
|
||||
|
||||
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
|
||||
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
|
||||
|
||||
// ****************
|
||||
// Private variables
|
||||
@ -200,6 +203,9 @@ static void gpsTask(__attribute__((unused)) void *parameters)
|
||||
portTickType xDelay = 100 / portTICK_RATE_MS;
|
||||
uint32_t timeNowMs = xTaskGetTickCount() * portTICK_RATE_MS;
|
||||
|
||||
#ifdef PIOS_GPS_SETS_HOMELOCATION
|
||||
portTickType homelocationSetDelay = 0;
|
||||
#endif
|
||||
GPSPositionSensorData gpspositionsensor;
|
||||
GPSSettingsData gpsSettings;
|
||||
|
||||
@ -260,7 +266,15 @@ static void gpsTask(__attribute__((unused)) void *parameters)
|
||||
HomeLocationGet(&home);
|
||||
|
||||
if (home.Set == HOMELOCATION_SET_FALSE) {
|
||||
setHomeLocation(&gpspositionsensor);
|
||||
if (homelocationSetDelay == 0) {
|
||||
homelocationSetDelay = xTaskGetTickCount();
|
||||
}
|
||||
if (xTaskGetTickCount() - homelocationSetDelay > GPS_HOMELOCATION_SET_DELAY) {
|
||||
setHomeLocation(&gpspositionsensor);
|
||||
homelocationSetDelay = 0;
|
||||
}
|
||||
} else {
|
||||
homelocationSetDelay = 0;
|
||||
}
|
||||
#endif
|
||||
} else if ((gpspositionsensor.Status == GPSPOSITIONSENSOR_STATUS_FIX3D) &&
|
||||
|
@ -274,6 +274,9 @@ static bool okToArm(void)
|
||||
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED1:
|
||||
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED2:
|
||||
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED3:
|
||||
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED4:
|
||||
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED5:
|
||||
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED6:
|
||||
return true;
|
||||
|
||||
break;
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include <revocalibration.h>
|
||||
|
||||
#include <CoordinateConversions.h>
|
||||
|
||||
#include <pios_notify.h>
|
||||
// Private constants
|
||||
|
||||
#define STACK_REQUIRED 512
|
||||
@ -295,6 +295,7 @@ static int32_t complementaryFilter(struct data *this, float gyro[3], float accel
|
||||
this->accel_filter_enabled = false;
|
||||
this->rollPitchBiasRate = 0.01f;
|
||||
this->attitudeSettings.MagKp = this->magCalibrated ? 1.0f : 0.0f;
|
||||
PIOS_NOTIFY_StartNotification(NOTIFY_DRAW_ATTENTION, NOTIFY_PRIORITY_REGULAR);
|
||||
} else if ((this->attitudeSettings.ZeroDuringArming == ATTITUDESETTINGS_ZERODURINGARMING_TRUE) && (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMING)) {
|
||||
this->attitudeSettings.AccelKp = 1.0f;
|
||||
this->attitudeSettings.AccelKi = 0.0f;
|
||||
@ -303,6 +304,7 @@ static int32_t complementaryFilter(struct data *this, float gyro[3], float accel
|
||||
this->rollPitchBiasRate = 0.01f;
|
||||
this->attitudeSettings.MagKp = this->magCalibrated ? 1.0f : 0.0f;
|
||||
this->init = 0;
|
||||
PIOS_NOTIFY_StartNotification(NOTIFY_DRAW_ATTENTION, NOTIFY_PRIORITY_REGULAR);
|
||||
} else if (this->init == 0) {
|
||||
// Reload settings (all the rates)
|
||||
AttitudeSettingsGet(&this->attitudeSettings);
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include <pios_struct_helper.h>
|
||||
// private includes
|
||||
#include "inc/systemmod.h"
|
||||
|
||||
#include "notification.h"
|
||||
|
||||
// UAVOs
|
||||
#include <objectpersistence.h>
|
||||
@ -72,22 +72,15 @@
|
||||
#endif
|
||||
|
||||
// Private constants
|
||||
#define SYSTEM_UPDATE_PERIOD_MS 1000
|
||||
#define LED_BLINK_RATE_HZ 5
|
||||
|
||||
#ifndef IDLE_COUNTS_PER_SEC_AT_NO_LOAD
|
||||
#define IDLE_COUNTS_PER_SEC_AT_NO_LOAD 995998 // calibrated by running tests/test_cpuload.c
|
||||
// must be updated if the FreeRTOS or compiler
|
||||
// optimisation options are changed.
|
||||
#endif
|
||||
#define SYSTEM_UPDATE_PERIOD_MS 250
|
||||
|
||||
#if defined(PIOS_SYSTEM_STACK_SIZE)
|
||||
#define STACK_SIZE_BYTES PIOS_SYSTEM_STACK_SIZE
|
||||
#define STACK_SIZE_BYTES PIOS_SYSTEM_STACK_SIZE
|
||||
#else
|
||||
#define STACK_SIZE_BYTES 1024
|
||||
#define STACK_SIZE_BYTES 1024
|
||||
#endif
|
||||
|
||||
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
|
||||
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
|
||||
|
||||
// Private types
|
||||
|
||||
@ -98,6 +91,7 @@ static enum { STACKOVERFLOW_NONE = 0, STACKOVERFLOW_WARNING = 1, STACKOVERFLOW_C
|
||||
static bool mallocFailed;
|
||||
static HwSettingsData bootHwSettings;
|
||||
static struct PIOS_FLASHFS_Stats fsStats;
|
||||
|
||||
// Private functions
|
||||
static void objectUpdatedCb(UAVObjEvent *ev);
|
||||
static void hwSettingsUpdatedCb(UAVObjEvent *ev);
|
||||
@ -170,8 +164,6 @@ MODULE_INITCALL(SystemModInitialize, 0);
|
||||
*/
|
||||
static void systemTask(__attribute__((unused)) void *parameters)
|
||||
{
|
||||
uint8_t cycleCount = 0;
|
||||
|
||||
/* create all modules thread */
|
||||
MODULE_TASKCREATE_ALL;
|
||||
|
||||
@ -189,9 +181,6 @@ static void systemTask(__attribute__((unused)) void *parameters)
|
||||
/* Record a successful boot */
|
||||
PIOS_IAP_WriteBootCount(0);
|
||||
#endif
|
||||
|
||||
// Initialize vars
|
||||
|
||||
// Listen for SettingPersistance object updates, connect a callback function
|
||||
ObjectPersistenceConnectQueue(objectPersistenceQueue);
|
||||
|
||||
@ -204,13 +193,10 @@ static void systemTask(__attribute__((unused)) void *parameters)
|
||||
TaskInfoData taskInfoData;
|
||||
CallbackInfoData callbackInfoData;
|
||||
#endif
|
||||
|
||||
// Main system loop
|
||||
while (1) {
|
||||
NotificationUpdateStatus();
|
||||
// Update the system statistics
|
||||
|
||||
cycleCount = cycleCount > 0 ? cycleCount - 1 : 7;
|
||||
// if(cycleCount == 1){
|
||||
updateStats();
|
||||
// Update the system alarms
|
||||
updateSystemAlarms();
|
||||
@ -230,35 +216,10 @@ static void systemTask(__attribute__((unused)) void *parameters)
|
||||
// }
|
||||
#endif
|
||||
// }
|
||||
// Flash the heartbeat LED
|
||||
#if defined(PIOS_LED_HEARTBEAT)
|
||||
uint8_t armingStatus;
|
||||
FlightStatusArmedGet(&armingStatus);
|
||||
if ((armingStatus == FLIGHTSTATUS_ARMED_ARMED && (cycleCount & 0x1)) ||
|
||||
(armingStatus != FLIGHTSTATUS_ARMED_ARMED && (cycleCount & 0x4))) {
|
||||
PIOS_LED_On(PIOS_LED_HEARTBEAT);
|
||||
} else {
|
||||
PIOS_LED_Off(PIOS_LED_HEARTBEAT);
|
||||
}
|
||||
|
||||
DEBUG_MSG("+ 0x%08x\r\n", 0xDEADBEEF);
|
||||
#endif /* PIOS_LED_HEARTBEAT */
|
||||
|
||||
// Turn on the error LED if an alarm is set
|
||||
#if defined(PIOS_LED_ALARM)
|
||||
if (AlarmsHasCritical()) {
|
||||
PIOS_LED_On(PIOS_LED_ALARM);
|
||||
} else if ((AlarmsHasErrors() && (cycleCount & 0x1)) ||
|
||||
(!AlarmsHasErrors() && AlarmsHasWarnings() && (cycleCount & 0x4))) {
|
||||
PIOS_LED_On(PIOS_LED_ALARM);
|
||||
} else {
|
||||
PIOS_LED_Off(PIOS_LED_ALARM);
|
||||
}
|
||||
#endif /* PIOS_LED_ALARM */
|
||||
|
||||
|
||||
UAVObjEvent ev;
|
||||
int delayTime = SYSTEM_UPDATE_PERIOD_MS / portTICK_RATE_MS / (LED_BLINK_RATE_HZ * 2);
|
||||
int delayTime = SYSTEM_UPDATE_PERIOD_MS;
|
||||
|
||||
#if defined(PIOS_INCLUDE_RFM22B)
|
||||
|
||||
@ -633,7 +594,7 @@ static void updateSystemAlarms()
|
||||
UAVObjClearStats();
|
||||
EventClearStats();
|
||||
if (objStats.eventCallbackErrors > 0 || objStats.eventQueueErrors > 0 || evStats.eventErrors > 0) {
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_EVENTSYSTEM, SYSTEMALARMS_ALARM_WARNING);
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_EVENTSYSTEM, SYSTEMALARMS_ALARM_ERROR);
|
||||
} else {
|
||||
AlarmsClear(SYSTEMALARMS_ALARM_EVENTSYSTEM);
|
||||
}
|
||||
@ -649,11 +610,12 @@ 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,
|
||||
*/
|
||||
void vApplicationIdleHook(void)
|
||||
{}
|
||||
|
||||
{
|
||||
NotificationOnboardLedsRun();
|
||||
}
|
||||
/**
|
||||
* Called by the RTOS when a stack overflow is detected.
|
||||
*/
|
||||
|
@ -661,11 +661,10 @@ static void updateTelemetryStats()
|
||||
flightStats.Status = FLIGHTTELEMETRYSTATS_STATUS_DISCONNECTED;
|
||||
}
|
||||
|
||||
// Update the telemetry alarm
|
||||
// TODO: check whether is there any error condition worth raising an alarm
|
||||
// Disconnection is actually a normal (non)working status so it is not raising alarms anymore.
|
||||
if (flightStats.Status == FLIGHTTELEMETRYSTATS_STATUS_CONNECTED) {
|
||||
AlarmsClear(SYSTEMALARMS_ALARM_TELEMETRY);
|
||||
} else {
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_TELEMETRY, SYSTEMALARMS_ALARM_ERROR);
|
||||
}
|
||||
|
||||
// Update object
|
||||
|
49
flight/pios/common/pios_notify.c
Normal file
49
flight/pios/common/pios_notify.c
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file pios_notify.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
|
||||
* @brief Handles user notifications.
|
||||
* --
|
||||
* @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 "pios_notify.h"
|
||||
|
||||
static volatile pios_notify_notification currentNotification = NOTIFY_NONE;
|
||||
static volatile pios_notify_priority currentPriority;
|
||||
|
||||
|
||||
void PIOS_NOTIFY_StartNotification(pios_notify_notification notification, pios_notify_priority priority)
|
||||
{
|
||||
if (currentNotification == NOTIFY_NONE || currentPriority < priority) {
|
||||
currentPriority = priority;
|
||||
currentNotification = notification;
|
||||
}
|
||||
}
|
||||
|
||||
pios_notify_notification PIOS_NOTIFY_GetActiveNotification(bool clear)
|
||||
{
|
||||
pios_notify_notification ret = currentNotification;
|
||||
|
||||
if (clear && ret != NOTIFY_NONE) {
|
||||
currentNotification = NOTIFY_NONE;
|
||||
}
|
||||
return ret;
|
||||
}
|
58
flight/pios/inc/pios_notify.h
Normal file
58
flight/pios/inc/pios_notify.h
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file pios_notify.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
|
||||
* @brief Handles user notifications.
|
||||
* --
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef PIOS_NOTIFY_H_
|
||||
#define PIOS_NOTIFY_H_
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum {
|
||||
NOTIFY_NONE = 0,
|
||||
NOTIFY_OK,
|
||||
NOTIFY_NOK,
|
||||
NOTIFY_DRAW_ATTENTION
|
||||
} pios_notify_notification;
|
||||
|
||||
typedef enum {
|
||||
NOTIFY_PRIORITY_CRITICAL = 2,
|
||||
NOTIFY_PRIORITY_REGULAR = 1,
|
||||
NOTIFY_PRIORITY_LOW = 0,
|
||||
} pios_notify_priority;
|
||||
|
||||
/**
|
||||
* start a new notification. If a notification is active it will be overwritten if its priority is lower than the new one.
|
||||
* The new will be discarded otherwise
|
||||
* @param notification kind of notification
|
||||
* @param priority priority of the new notification
|
||||
*/
|
||||
void PIOS_NOTIFY_StartNotification(pios_notify_notification notification, pios_notify_priority priority);
|
||||
|
||||
/**
|
||||
* retrieve any active notification
|
||||
* @param clear
|
||||
* @return
|
||||
*/
|
||||
pios_notify_notification PIOS_NOTIFY_GetActiveNotification(bool clear);
|
||||
|
||||
#endif /* PIOS_NOTIFY_H_ */
|
147
flight/pios/inc/pios_ws2811.h
Normal file
147
flight/pios/inc/pios_ws2811.h
Normal file
@ -0,0 +1,147 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file pios_ws2811.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
|
||||
* @brief A driver for ws2811 rgb led controller.
|
||||
* this is a plain PiOS port of the very clever solution
|
||||
* implemented by Omri Iluz in the chibios driver here:
|
||||
* https://github.com/omriiluz/WS2812B-LED-Driver-ChibiOS
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef PIOS_WS2811_H_
|
||||
#define PIOS_WS2811_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <pios_gpio.h>
|
||||
#include <pios_stm32.h>
|
||||
#include <pios_gpio_priv.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <stm32f4xx_tim.h>
|
||||
#include <stm32f4xx_dma.h>
|
||||
|
||||
|
||||
#define sign(x) ((x > 0) - (x < 0))
|
||||
#define PIOS_WS2811_NUMLEDS 2
|
||||
#define PIOS_WS2811_BUFFER_SIZE (((PIOS_WS2811_NUMLEDS) * 24))
|
||||
#define PIOS_WS2811_MEMORYDATASIZE DMA_MemoryDataSize_HalfWord
|
||||
#define PIOS_WS2811_PERIPHERALDATASIZE DMA_PeripheralDataSize_HalfWord
|
||||
#define PIOS_WS2811_TIM_PERIOD 20
|
||||
|
||||
// Following times are keept on the lower side to accounts
|
||||
// for bus contentions and irq response time
|
||||
#define PIOS_WS2811_T0_HIGH_PERIOD 25 // .35us +/- 150nS
|
||||
#define PIOS_WS2811_T1_HIGH_PERIOD 60 // .70us +/- 150nS
|
||||
|
||||
#define PIOS_WS2811_DMA_CH1_CONFIG(channel) \
|
||||
{ \
|
||||
.DMA_BufferSize = PIOS_WS2811_BUFFER_SIZE, \
|
||||
.DMA_Channel = channel, \
|
||||
.DMA_DIR = DMA_DIR_MemoryToPeripheral, \
|
||||
.DMA_FIFOMode = DMA_FIFOMode_Enable, \
|
||||
.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull, \
|
||||
.DMA_Memory0BaseAddr = 0, \
|
||||
.DMA_MemoryBurst = DMA_MemoryBurst_INC4, \
|
||||
.DMA_MemoryDataSize = PIOS_WS2811_MEMORYDATASIZE, \
|
||||
.DMA_MemoryInc = DMA_MemoryInc_Enable, \
|
||||
.DMA_Mode = DMA_Mode_Circular, \
|
||||
.DMA_PeripheralBaseAddr = 0, \
|
||||
.DMA_PeripheralBurst = DMA_PeripheralBurst_Single, \
|
||||
.DMA_PeripheralDataSize = PIOS_WS2811_PERIPHERALDATASIZE, \
|
||||
.DMA_PeripheralInc = DMA_PeripheralInc_Disable, \
|
||||
.DMA_Priority = DMA_Priority_VeryHigh, }
|
||||
|
||||
#define PIOS_WS2811_DMA_CH2_CONFIG(channel) \
|
||||
{ \
|
||||
.DMA_BufferSize = 4, \
|
||||
.DMA_Channel = channel, \
|
||||
.DMA_DIR = DMA_DIR_MemoryToPeripheral, \
|
||||
.DMA_FIFOMode = DMA_FIFOMode_Enable, \
|
||||
.DMA_FIFOThreshold = DMA_FIFOThreshold_Full, \
|
||||
.DMA_Memory0BaseAddr = 0, \
|
||||
.DMA_MemoryBurst = DMA_MemoryBurst_INC4, \
|
||||
.DMA_MemoryDataSize = PIOS_WS2811_MEMORYDATASIZE, \
|
||||
.DMA_MemoryInc = DMA_MemoryInc_Enable, \
|
||||
.DMA_Mode = DMA_Mode_Circular, \
|
||||
.DMA_PeripheralBaseAddr = 0, \
|
||||
.DMA_PeripheralBurst = DMA_PeripheralBurst_Single, \
|
||||
.DMA_PeripheralDataSize = PIOS_WS2811_PERIPHERALDATASIZE, \
|
||||
.DMA_PeripheralInc = DMA_PeripheralInc_Disable, \
|
||||
.DMA_Priority = DMA_Priority_VeryHigh, }
|
||||
|
||||
#define PIOS_WS2811_DMA_UPDATE_CONFIG(channel) \
|
||||
{ \
|
||||
.DMA_BufferSize = 4, \
|
||||
.DMA_Channel = channel, \
|
||||
.DMA_DIR = DMA_DIR_MemoryToPeripheral, \
|
||||
.DMA_FIFOMode = DMA_FIFOMode_Enable, \
|
||||
.DMA_FIFOThreshold = DMA_FIFOThreshold_Full, \
|
||||
.DMA_Memory0BaseAddr = 0, \
|
||||
.DMA_MemoryBurst = DMA_MemoryBurst_INC4, \
|
||||
.DMA_MemoryDataSize = PIOS_WS2811_MEMORYDATASIZE, \
|
||||
.DMA_MemoryInc = DMA_MemoryInc_Enable, \
|
||||
.DMA_Mode = DMA_Mode_Circular, \
|
||||
.DMA_PeripheralBaseAddr = 0, \
|
||||
.DMA_PeripheralBurst = DMA_PeripheralBurst_Single, \
|
||||
.DMA_PeripheralDataSize = PIOS_WS2811_PERIPHERALDATASIZE, \
|
||||
.DMA_PeripheralInc = DMA_PeripheralInc_Disable, \
|
||||
.DMA_Priority = DMA_Priority_High }
|
||||
|
||||
|
||||
typedef uint16_t ledbuf_t;
|
||||
|
||||
typedef struct Color Color;
|
||||
struct Color {
|
||||
uint8_t R;
|
||||
uint8_t G;
|
||||
uint8_t B;
|
||||
};
|
||||
struct pios_ws2811_pin_cfg {
|
||||
GPIO_TypeDef *gpio;
|
||||
GPIO_InitTypeDef gpioInit;
|
||||
};
|
||||
struct pios_ws2811_cfg {
|
||||
TIM_TimeBaseInitTypeDef timerInit;
|
||||
TIM_TypeDef *timer;
|
||||
uint8_t timerCh1;
|
||||
uint8_t timerCh2;
|
||||
|
||||
DMA_InitTypeDef dmaInitCh1;
|
||||
DMA_Stream_TypeDef *streamCh1;
|
||||
uint32_t dmaItCh1;
|
||||
|
||||
DMA_InitTypeDef dmaInitCh2;
|
||||
DMA_Stream_TypeDef *streamCh2;
|
||||
uint32_t dmaItCh2;
|
||||
|
||||
DMA_InitTypeDef dmaInitUpdate;
|
||||
DMA_Stream_TypeDef *streamUpdate;
|
||||
uint32_t dmaItUpdate;
|
||||
uint16_t dmaSource;
|
||||
struct stm32_irq irq;
|
||||
};
|
||||
|
||||
void PIOS_WS2811_Init(const struct pios_ws2811_cfg *ws2811_cfg, const struct pios_ws2811_pin_cfg *ws2811_pin_cfg);
|
||||
|
||||
void PIOS_WS2811_setColorRGB(Color c, uint8_t led, bool update);
|
||||
void PIOS_WS2811_Update();
|
||||
|
||||
void PIOS_WS2811_DMA_irq_handler();
|
||||
|
||||
#endif /* PIOS_WS2811_H_ */
|
344
flight/pios/stm32f4xx/pios_ws2811.c
Normal file
344
flight/pios/stm32f4xx/pios_ws2811.c
Normal file
@ -0,0 +1,344 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file pios_ws2811.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
|
||||
* @brief A driver for ws2811 rgb led controller.
|
||||
* this is a plain PiOS port of the very clever solution
|
||||
* implemented by Omri Iluz in the chibios driver here:
|
||||
* https://github.com/omriiluz/WS2812B-LED-Driver-ChibiOS
|
||||
* @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 <pios.h>
|
||||
|
||||
#ifdef PIOS_INCLUDE_WS2811
|
||||
|
||||
#include "pios_ws2811.h"
|
||||
#include <stm32f4xx_rcc.h>
|
||||
#include <pios_stm32.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
|
||||
// framebuffer
|
||||
static ledbuf_t *fb = 0;
|
||||
// bitmask with pin to be set/reset using dma
|
||||
static ledbuf_t dmaSource[4];
|
||||
|
||||
static const struct pios_ws2811_cfg *pios_ws2811_cfg;
|
||||
static const struct pios_ws2811_pin_cfg *pios_ws2811_pin_cfg;
|
||||
|
||||
static void setupTimer();
|
||||
static void setupDMA();
|
||||
|
||||
// generic wrapper around corresponding SPL functions
|
||||
static void genericTIM_OCxInit(TIM_TypeDef *TIMx, const TIM_OCInitTypeDef *TIM_OCInitStruct, uint8_t ch);
|
||||
static void genericTIM_OCxPreloadConfig(TIM_TypeDef *TIMx, uint16_t TIM_OCPreload, uint8_t ch);
|
||||
|
||||
// timer creates a 1.25 uS signal, with duty cycle controlled by frame buffer values
|
||||
|
||||
/* Example configuration fragment for REVOLUTION
|
||||
|
||||
#ifdef PIOS_INCLUDE_WS2811
|
||||
#include <pios_ws2811.h>
|
||||
#include <hwsettings.h>
|
||||
#define PIOS_WS2811_TIM_DIVIDER (PIOS_PERIPHERAL_APB2_CLOCK / (800000 * PIOS_WS2811_TIM_PERIOD))
|
||||
|
||||
// interrupt vector for DMA streamCh1
|
||||
void DMA2_Stream1_IRQHandler(void) __attribute__((alias("PIOS_WS2811_irq_handler")));
|
||||
|
||||
const struct pios_ws2811_pin_cfg pios_ws2811_pin_cfg[] = {
|
||||
[HWSETTINGS_WS2811LED_OUT_SERVOOUT1] = {
|
||||
.gpio = GPIOB,
|
||||
.gpioInit = {
|
||||
.GPIO_Pin = GPIO_Pin_0,
|
||||
.GPIO_Speed = GPIO_Speed_25MHz,
|
||||
.GPIO_Mode = GPIO_Mode_OUT,
|
||||
.GPIO_OType = GPIO_OType_PP,
|
||||
},
|
||||
},
|
||||
....
|
||||
[HWSETTINGS_WS2811LED_OUT_FLEXIPIN4] = {
|
||||
.gpio = GPIOB,
|
||||
.gpioInit = {
|
||||
.GPIO_Pin = GPIO_Pin_13,
|
||||
.GPIO_Speed = GPIO_Speed_25MHz,
|
||||
.GPIO_Mode = GPIO_Mode_OUT,
|
||||
.GPIO_OType = GPIO_OType_PP,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const struct pios_ws2811_cfg pios_ws2811_cfg = {
|
||||
.timer = TIM1,
|
||||
.timerInit = {
|
||||
.TIM_Prescaler = PIOS_WS2811_TIM_DIVIDER - 1,
|
||||
.TIM_ClockDivision = TIM_CKD_DIV1,
|
||||
.TIM_CounterMode = TIM_CounterMode_Up,
|
||||
// period (1.25 uS per period
|
||||
.TIM_Period = PIOS_WS2811_TIM_PERIOD,
|
||||
.TIM_RepetitionCounter = 0x0000,
|
||||
},
|
||||
|
||||
.timerCh1 = 1,
|
||||
.streamCh1 = DMA2_Stream1,
|
||||
.timerCh2 = 3,
|
||||
.streamCh2 = DMA2_Stream6,
|
||||
.streamUpdate = DMA2_Stream5,
|
||||
|
||||
// DMA streamCh1, triggered by timerCh1 pwm signal.
|
||||
// if FrameBuffer indicates, reset output value early to indicate "0" bit to ws2812
|
||||
.dmaInitCh1 = PIOS_WS2811_DMA_UPDATE_CONFIG(DMA_Channel_6),
|
||||
.dmaItCh1 = DMA_IT_TEIF1 | DMA_IT_TCIF1,
|
||||
|
||||
// DMA streamCh2, triggered by timerCh2 pwm signal.
|
||||
// Reset output value late to indicate "1" bit to ws2812.
|
||||
.dmaInitCh2 = PIOS_WS2811_DMA_CH1_CONFIG(DMA_Channel_6),
|
||||
.dmaItCh2 = DMA_IT_TEIF6 | DMA_IT_TCIF6,
|
||||
|
||||
// DMA streamUpdate Triggered by timer update event
|
||||
// Outputs a high logic level at beginning of a cycle
|
||||
.dmaInitUpdate = PIOS_WS2811_DMA_CH2_CONFIG(DMA_Channel_6),
|
||||
.dmaItUpdate = DMA_IT_TEIF5 | DMA_IT_TCIF5,
|
||||
.dmaSource = TIM_DMA_CC1 | TIM_DMA_CC3 | TIM_DMA_Update,
|
||||
|
||||
// DMA streamCh1 interrupt vector, used to block timer at end of framebuffer transfer
|
||||
.irq = {
|
||||
.flags = (DMA_IT_TCIF1),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA2_Stream1_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
.NVIC_IRQChannelCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
void PIOS_WS2811_irq_handler(void)
|
||||
{
|
||||
PIOS_WS2811_DMA_irq_handler();
|
||||
}
|
||||
#endif // PIOS_INCLUDE_WS2811
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* How it works:
|
||||
* a timer and two channels will produce the timings events:
|
||||
* timer period will be 1.25us
|
||||
* Ch1 CC event will be raised at 0.40uS from the beginning of the cycle
|
||||
* Ch2 CC event will be raised at 0.80uS from the beginning of the cycle
|
||||
* At cycle init an Update event will be raised.
|
||||
*
|
||||
* Three dma streams will handle the output pin as following:
|
||||
* - streamUpdate dma stream, triggered by update event will produce a logic 1 on the output pin
|
||||
* - streamCh1 will bring the pin to 0 if framebuffer location is set to dmaSource value to send a "0" bit to WS281x
|
||||
* - streamCh2 will bring pin to 0 once .8us are passed to send a "1" bit to ws281x
|
||||
* Once StreamCh1 has finished to send the buffer the IRQ handler will stop the timer.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize WS2811 Led Driver
|
||||
* @details Initialize the Led Driver based on passed configuration
|
||||
*
|
||||
* @param[in] ws2811_cfg ws2811 driver configuration
|
||||
* @param[in] ws2811_pin_cfg pin to be used as output
|
||||
*
|
||||
*/
|
||||
|
||||
void PIOS_WS2811_Init(const struct pios_ws2811_cfg *ws2811_cfg, const struct pios_ws2811_pin_cfg *ws2811_pin_cfg)
|
||||
{
|
||||
assert_param(ws2811_cfg);
|
||||
assert_param(ws2811_pin_cfg);
|
||||
|
||||
pios_ws2811_pin_cfg = ws2811_pin_cfg;
|
||||
pios_ws2811_cfg = ws2811_cfg;
|
||||
GPIO_Init(pios_ws2811_pin_cfg->gpio, &pios_ws2811_pin_cfg->gpioInit);
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
dmaSource[i] = (ledbuf_t)pios_ws2811_pin_cfg->gpioInit.GPIO_Pin;
|
||||
}
|
||||
|
||||
fb = (ledbuf_t *)pvPortMalloc(PIOS_WS2811_BUFFER_SIZE * sizeof(ledbuf_t));
|
||||
memset(fb, 0, PIOS_WS2811_BUFFER_SIZE * sizeof(ledbuf_t));
|
||||
Color ledoff = { 0, 0, 0 };
|
||||
for (uint8_t i = 0; i < PIOS_WS2811_NUMLEDS; i++) {
|
||||
PIOS_WS2811_setColorRGB(ledoff, i, false);
|
||||
}
|
||||
// Setup timers
|
||||
setupTimer();
|
||||
setupDMA();
|
||||
}
|
||||
|
||||
void setupTimer()
|
||||
{
|
||||
// Stop timer
|
||||
TIM_Cmd(pios_ws2811_cfg->timer, DISABLE);
|
||||
// Configure timebase and internal clock
|
||||
TIM_TimeBaseInit(pios_ws2811_cfg->timer, &pios_ws2811_cfg->timerInit);
|
||||
TIM_InternalClockConfig(pios_ws2811_cfg->timer);
|
||||
|
||||
genericTIM_OCxPreloadConfig(pios_ws2811_cfg->timer, TIM_OCPreload_Enable, pios_ws2811_cfg->timerCh1);
|
||||
genericTIM_OCxPreloadConfig(pios_ws2811_cfg->timer, TIM_OCPreload_Enable, pios_ws2811_cfg->timerCh2);
|
||||
TIM_ARRPreloadConfig(pios_ws2811_cfg->timer, ENABLE);
|
||||
|
||||
// enable outputs
|
||||
// TIM_CtrlPWMOutputs(pios_ws2811_cfg->timer, ENABLE);
|
||||
|
||||
TIM_DMACmd(pios_ws2811_cfg->timer, pios_ws2811_cfg->dmaSource, ENABLE);
|
||||
|
||||
TIM_OCInitTypeDef oc = {
|
||||
.TIM_OCMode = TIM_OCMode_PWM1,
|
||||
.TIM_OutputState = TIM_OutputState_Enable,
|
||||
.TIM_OutputNState = TIM_OutputNState_Disable,
|
||||
.TIM_Pulse = 0,
|
||||
.TIM_OCPolarity = TIM_OCPolarity_High,
|
||||
.TIM_OCNPolarity = TIM_OCNPolarity_High,
|
||||
.TIM_OCIdleState = TIM_OCIdleState_Reset,
|
||||
.TIM_OCNIdleState = TIM_OCNIdleState_Reset,
|
||||
};
|
||||
|
||||
// (duty in ticks) / (period in ticks) * 1.25uS (period in S) = 0.40 uS
|
||||
oc.TIM_Pulse = PIOS_WS2811_T0_HIGH_PERIOD * PIOS_WS2811_TIM_PERIOD / 125;
|
||||
genericTIM_OCxInit(pios_ws2811_cfg->timer, &oc, pios_ws2811_cfg->timerCh1);
|
||||
// (duty in ticks) / (period in ticks) * 1.25uS (period in S) = 0.80 uS
|
||||
oc.TIM_Pulse = PIOS_WS2811_T1_HIGH_PERIOD * PIOS_WS2811_TIM_PERIOD / 125;
|
||||
genericTIM_OCxInit(pios_ws2811_cfg->timer, &oc, pios_ws2811_cfg->timerCh2);
|
||||
}
|
||||
|
||||
void genericTIM_OCxInit(TIM_TypeDef *TIMx, const TIM_OCInitTypeDef *TIM_OCInitStruct, uint8_t ch)
|
||||
{
|
||||
switch (ch) {
|
||||
case 1:
|
||||
TIM_OC1Init(TIMx, TIM_OCInitStruct);
|
||||
break;
|
||||
case 2:
|
||||
TIM_OC2Init(TIMx, TIM_OCInitStruct);
|
||||
break;
|
||||
case 3:
|
||||
TIM_OC3Init(TIMx, TIM_OCInitStruct);
|
||||
break;
|
||||
case 4:
|
||||
TIM_OC4Init(TIMx, TIM_OCInitStruct);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void genericTIM_OCxPreloadConfig(TIM_TypeDef *TIMx, uint16_t TIM_OCPreload, uint8_t ch)
|
||||
{
|
||||
switch (ch) {
|
||||
case 1:
|
||||
TIM_OC1PreloadConfig(TIMx, TIM_OCPreload);
|
||||
break;
|
||||
case 2:
|
||||
TIM_OC2PreloadConfig(TIMx, TIM_OCPreload);
|
||||
break;
|
||||
case 3:
|
||||
TIM_OC3PreloadConfig(TIMx, TIM_OCPreload);
|
||||
break;
|
||||
case 4:
|
||||
TIM_OC4PreloadConfig(TIMx, TIM_OCPreload);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setupDMA()
|
||||
{
|
||||
// Configure Ch1
|
||||
DMA_Init(pios_ws2811_cfg->streamCh1, (DMA_InitTypeDef *)&pios_ws2811_cfg->dmaInitCh1);
|
||||
pios_ws2811_cfg->streamCh1->PAR = (uint32_t)&pios_ws2811_pin_cfg->gpio->BSRRH;
|
||||
pios_ws2811_cfg->streamCh1->M0AR = (uint32_t)fb;
|
||||
|
||||
NVIC_Init((NVIC_InitTypeDef *)&(pios_ws2811_cfg->irq.init));
|
||||
DMA_ITConfig(pios_ws2811_cfg->streamCh1, DMA_IT_TC, ENABLE);
|
||||
|
||||
|
||||
DMA_Init(pios_ws2811_cfg->streamCh2, (DMA_InitTypeDef *)&pios_ws2811_cfg->dmaInitCh2);
|
||||
pios_ws2811_cfg->streamCh2->PAR = (uint32_t)&pios_ws2811_pin_cfg->gpio->BSRRH;
|
||||
pios_ws2811_cfg->streamCh2->M0AR = (uint32_t)dmaSource;
|
||||
|
||||
DMA_Init(pios_ws2811_cfg->streamUpdate, (DMA_InitTypeDef *)&pios_ws2811_cfg->dmaInitUpdate);
|
||||
pios_ws2811_cfg->streamUpdate->PAR = (uint32_t)&pios_ws2811_pin_cfg->gpio->BSRRL;
|
||||
pios_ws2811_cfg->streamUpdate->M0AR = (uint32_t)dmaSource;
|
||||
|
||||
DMA_ClearITPendingBit(pios_ws2811_cfg->streamCh1, pios_ws2811_cfg->dmaItCh1);
|
||||
DMA_ClearITPendingBit(pios_ws2811_cfg->streamCh2, pios_ws2811_cfg->dmaItCh2);
|
||||
DMA_ClearITPendingBit(pios_ws2811_cfg->streamUpdate, pios_ws2811_cfg->dmaItUpdate);
|
||||
|
||||
DMA_Cmd(pios_ws2811_cfg->streamCh2, ENABLE);
|
||||
DMA_Cmd(pios_ws2811_cfg->streamCh1, ENABLE);
|
||||
DMA_Cmd(pios_ws2811_cfg->streamUpdate, ENABLE);
|
||||
}
|
||||
|
||||
void setColor(uint8_t color, ledbuf_t *buf)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
buf[i] = ((color << i) & 0b10000000 ? 0x0 : dmaSource[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a led color
|
||||
* @param c color
|
||||
* @param led led number
|
||||
* @param update Perform an update after changing led color
|
||||
*/
|
||||
void PIOS_WS2811_setColorRGB(Color c, uint8_t led, bool update)
|
||||
{
|
||||
if (led >= PIOS_WS2811_NUMLEDS) {
|
||||
return;
|
||||
}
|
||||
setColor(c.G, fb + (led * 24));
|
||||
setColor(c.R, fb + 8 + (led * 24));
|
||||
setColor(c.B, fb + 16 + (led * 24));
|
||||
if (update) {
|
||||
PIOS_WS2811_Update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* trigger an update cycle if not already running
|
||||
*/
|
||||
void PIOS_WS2811_Update()
|
||||
{
|
||||
// does not start if framebuffer is not allocated (init has not been called yet) or a transfer is still on going
|
||||
if (!fb || (pios_ws2811_cfg->timer->CR1 & TIM_CR1_CEN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// reset counters for synchronization
|
||||
pios_ws2811_cfg->timer->CNT = PIOS_WS2811_TIM_PERIOD - 1;
|
||||
// Start a new cycle
|
||||
TIM_Cmd(pios_ws2811_cfg->timer, ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop timer once the complete framebuffer has been sent
|
||||
*/
|
||||
|
||||
void PIOS_WS2811_DMA_irq_handler()
|
||||
{
|
||||
pios_ws2811_cfg->timer->CR1 &= (uint16_t) ~TIM_CR1_CEN;
|
||||
DMA_ClearFlag(pios_ws2811_cfg->streamCh1, pios_ws2811_cfg->irq.flags);
|
||||
}
|
||||
|
||||
#endif // PIOS_INCLUDE_WS2811
|
@ -48,9 +48,13 @@ OPTMODULES += Osd/osdoutput
|
||||
#OPTMODULES += Altitude
|
||||
#OPTMODULES += Fault
|
||||
|
||||
SRC += $(FLIGHTLIB)/notification.c
|
||||
|
||||
# Include all camera options
|
||||
CDEFS += -DUSE_INPUT_LPF -DUSE_GIMBAL_LPF -DUSE_GIMBAL_FF
|
||||
|
||||
|
||||
|
||||
# Erase flash firmware should be buildable from command line
|
||||
ifeq ($(ERASE_FLASH), YES)
|
||||
CDEFS += -DERASE_FLASH
|
||||
|
@ -1810,3 +1810,69 @@ const struct pios_usb_hid_cfg pios_usb_hid_cfg = {
|
||||
.data_tx_ep = 1,
|
||||
};
|
||||
#endif /* PIOS_INCLUDE_USB_HID && PIOS_INCLUDE_USB_CDC */
|
||||
#ifdef PIOS_INCLUDE_WS2811
|
||||
#include <pios_ws2811.h>
|
||||
#define PIOS_WS2811_TIM_DIVIDER (PIOS_PERIPHERAL_APB2_CLOCK / (800000 * PIOS_WS2811_TIM_PERIOD))
|
||||
|
||||
void DMA2_Stream1_IRQHandler(void) __attribute__((alias("PIOS_WS2811_irq_handler")));
|
||||
|
||||
const struct pios_ws2811_pin_cfg pios_ws2811_pin_cfg = {
|
||||
.gpio = GPIOA,
|
||||
.gpioInit = {
|
||||
.GPIO_Pin = GPIO_Pin_3,
|
||||
.GPIO_Speed = GPIO_Speed_50MHz,
|
||||
.GPIO_Mode = GPIO_Mode_OUT,
|
||||
.GPIO_OType = GPIO_OType_PP,
|
||||
},
|
||||
};
|
||||
|
||||
const struct pios_ws2811_cfg pios_ws2811_cfg = {
|
||||
.timer = TIM1,
|
||||
.timerInit = {
|
||||
.TIM_Prescaler = PIOS_WS2811_TIM_DIVIDER - 1,
|
||||
.TIM_ClockDivision = TIM_CKD_DIV1,
|
||||
.TIM_CounterMode = TIM_CounterMode_Up,
|
||||
// period (1.25 uS per period
|
||||
.TIM_Period = PIOS_WS2811_TIM_PERIOD,
|
||||
.TIM_RepetitionCounter = 0x0000,
|
||||
},
|
||||
|
||||
.timerCh1 = 1,
|
||||
.streamCh1 = DMA2_Stream1,
|
||||
.timerCh2 = 3,
|
||||
.streamCh2 = DMA2_Stream6,
|
||||
.streamUpdate = DMA2_Stream5,
|
||||
|
||||
// DMA streamCh1, triggered by timerCh1 pwm signal.
|
||||
// if FrameBuffer indicates, reset output value early to indicate "0" bit to ws2812
|
||||
.dmaInitCh1 = PIOS_WS2811_DMA_CH1_CONFIG(DMA_Channel_6),
|
||||
.dmaItCh1 = DMA_IT_TEIF1 | DMA_IT_TCIF1,
|
||||
|
||||
// DMA streamCh2, triggered by timerCh2 pwm signal.
|
||||
// Reset output value late to indicate "1" bit to ws2812.
|
||||
.dmaInitCh2 = PIOS_WS2811_DMA_CH2_CONFIG(DMA_Channel_6),
|
||||
.dmaItCh2 = DMA_IT_TEIF6 | DMA_IT_TCIF6,
|
||||
|
||||
// DMA streamUpdate Triggered by timer update event
|
||||
// Outputs a high logic level at beginning of a cycle
|
||||
.dmaInitUpdate = PIOS_WS2811_DMA_UPDATE_CONFIG(DMA_Channel_6),
|
||||
.dmaItUpdate = DMA_IT_TEIF5 | DMA_IT_TCIF5,
|
||||
.dmaSource = TIM_DMA_CC1 | TIM_DMA_CC3 | TIM_DMA_Update,
|
||||
|
||||
// DMA streamCh1 interrupt vector, used to block timer at end of framebuffer transfer
|
||||
.irq = {
|
||||
.flags = (DMA_IT_TCIF1),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA2_Stream1_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
.NVIC_IRQChannelCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
void PIOS_WS2811_irq_handler(void)
|
||||
{
|
||||
PIOS_WS2811_DMA_irq_handler();
|
||||
}
|
||||
#endif // PIOS_INCLUDE_WS2811
|
||||
|
@ -52,6 +52,8 @@ MODULES += Telemetry
|
||||
|
||||
OPTMODULES += ComUsbBridge
|
||||
|
||||
SRC += $(FLIGHTLIB)/notification.c
|
||||
|
||||
# Include all camera options
|
||||
CDEFS += -DUSE_INPUT_LPF -DUSE_GIMBAL_LPF -DUSE_GIMBAL_FF
|
||||
|
||||
|
@ -88,6 +88,7 @@
|
||||
// #define PIOS_INCLUDE_MPXV
|
||||
// #define PIOS_INCLUDE_ETASV3
|
||||
/* #define PIOS_INCLUDE_HCSR04 */
|
||||
#define PIOS_INCLUDE_WS2811
|
||||
|
||||
/* PIOS receiver drivers */
|
||||
#define PIOS_INCLUDE_PWM
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include <pios_oplinkrcvr_priv.h>
|
||||
#include <taskinfo.h>
|
||||
#include <pios_callbackscheduler.h>
|
||||
|
||||
/*
|
||||
* Pull in the board-specific static HW definitions.
|
||||
* Including .c files is a bit ugly but this allows all of
|
||||
@ -932,6 +931,11 @@ void PIOS_Board_Init(void)
|
||||
PIOS_MPU6000_Init(pios_spi_gyro_id, 0, &pios_mpu6000_cfg);
|
||||
PIOS_MPU6000_CONFIG_Configure();
|
||||
#endif
|
||||
|
||||
#ifdef PIOS_INCLUDE_WS2811
|
||||
#include <pios_ws2811.h>
|
||||
PIOS_WS2811_Init(&pios_ws2811_cfg, &pios_ws2811_pin_cfg);
|
||||
#endif // PIOS_INCLUDE_WS2811
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,6 +37,8 @@ MODULES += Telemetry
|
||||
|
||||
OPTMODULES =
|
||||
|
||||
SRC += $(FLIGHTLIB)/notification.c
|
||||
|
||||
# Some diagnostics
|
||||
CDEFS += -DDIAG_TASKS
|
||||
|
||||
|
@ -1962,3 +1962,138 @@ const struct pios_usb_hid_cfg pios_usb_hid_cfg = {
|
||||
.data_tx_ep = 1,
|
||||
};
|
||||
#endif /* PIOS_INCLUDE_USB_HID && PIOS_INCLUDE_USB_CDC */
|
||||
|
||||
#ifdef PIOS_INCLUDE_WS2811
|
||||
#include <pios_ws2811.h>
|
||||
#include <hwsettings.h>
|
||||
#define PIOS_WS2811_TIM_DIVIDER (PIOS_PERIPHERAL_APB2_CLOCK / (800000 * PIOS_WS2811_TIM_PERIOD))
|
||||
|
||||
void DMA2_Stream1_IRQHandler(void) __attribute__((alias("PIOS_WS2811_irq_handler")));
|
||||
// list of pin configurable as ws281x outputs.
|
||||
// this will not clash with PWM in or servo output as
|
||||
// pins will be reconfigured as _OUT so the alternate function is disabled.
|
||||
const struct pios_ws2811_pin_cfg pios_ws2811_pin_cfg[] = {
|
||||
[HWSETTINGS_WS2811LED_OUT_SERVOOUT1] = {
|
||||
.gpio = GPIOB,
|
||||
.gpioInit = {
|
||||
.GPIO_Pin = GPIO_Pin_0,
|
||||
.GPIO_Speed = GPIO_Speed_25MHz,
|
||||
.GPIO_Mode = GPIO_Mode_OUT,
|
||||
.GPIO_OType = GPIO_OType_PP,
|
||||
},
|
||||
},
|
||||
[HWSETTINGS_WS2811LED_OUT_SERVOOUT2] = {
|
||||
.gpio = GPIOB,
|
||||
.gpioInit = {
|
||||
.GPIO_Pin = GPIO_Pin_1,
|
||||
.GPIO_Speed = GPIO_Speed_25MHz,
|
||||
.GPIO_Mode = GPIO_Mode_OUT,
|
||||
.GPIO_OType = GPIO_OType_PP,
|
||||
},
|
||||
},
|
||||
[HWSETTINGS_WS2811LED_OUT_SERVOOUT3] = {
|
||||
.gpio = GPIOA,
|
||||
.gpioInit = {
|
||||
.GPIO_Pin = GPIO_Pin_3,
|
||||
.GPIO_Speed = GPIO_Speed_25MHz,
|
||||
.GPIO_Mode = GPIO_Mode_OUT,
|
||||
.GPIO_OType = GPIO_OType_PP,
|
||||
},
|
||||
},
|
||||
[HWSETTINGS_WS2811LED_OUT_SERVOOUT4] = {
|
||||
.gpio = GPIOA,
|
||||
.gpioInit = {
|
||||
.GPIO_Pin = GPIO_Pin_2,
|
||||
.GPIO_Speed = GPIO_Speed_25MHz,
|
||||
.GPIO_Mode = GPIO_Mode_OUT,
|
||||
.GPIO_OType = GPIO_OType_PP,
|
||||
},
|
||||
},
|
||||
[HWSETTINGS_WS2811LED_OUT_SERVOOUT5] = {
|
||||
.gpio = GPIOA,
|
||||
.gpioInit = {
|
||||
.GPIO_Pin = GPIO_Pin_1,
|
||||
.GPIO_Speed = GPIO_Speed_25MHz,
|
||||
.GPIO_Mode = GPIO_Mode_OUT,
|
||||
.GPIO_OType = GPIO_OType_PP,
|
||||
},
|
||||
},
|
||||
[HWSETTINGS_WS2811LED_OUT_SERVOOUT6] = {
|
||||
.gpio = GPIOA,
|
||||
.gpioInit = {
|
||||
.GPIO_Pin = GPIO_Pin_0,
|
||||
.GPIO_Speed = GPIO_Speed_25MHz,
|
||||
.GPIO_Mode = GPIO_Mode_OUT,
|
||||
.GPIO_OType = GPIO_OType_PP,
|
||||
},
|
||||
},
|
||||
[HWSETTINGS_WS2811LED_OUT_FLEXIPIN3] = {
|
||||
.gpio = GPIOB,
|
||||
.gpioInit = {
|
||||
.GPIO_Pin = GPIO_Pin_12,
|
||||
.GPIO_Speed = GPIO_Speed_25MHz,
|
||||
.GPIO_Mode = GPIO_Mode_OUT,
|
||||
.GPIO_OType = GPIO_OType_PP,
|
||||
},
|
||||
},
|
||||
[HWSETTINGS_WS2811LED_OUT_FLEXIPIN4] = {
|
||||
.gpio = GPIOB,
|
||||
.gpioInit = {
|
||||
.GPIO_Pin = GPIO_Pin_13,
|
||||
.GPIO_Speed = GPIO_Speed_25MHz,
|
||||
.GPIO_Mode = GPIO_Mode_OUT,
|
||||
.GPIO_OType = GPIO_OType_PP,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const struct pios_ws2811_cfg pios_ws2811_cfg = {
|
||||
.timer = TIM1,
|
||||
.timerInit = {
|
||||
.TIM_Prescaler = PIOS_WS2811_TIM_DIVIDER - 1,
|
||||
.TIM_ClockDivision = TIM_CKD_DIV1,
|
||||
.TIM_CounterMode = TIM_CounterMode_Up,
|
||||
// period (1.25 uS per period
|
||||
.TIM_Period = PIOS_WS2811_TIM_PERIOD,
|
||||
.TIM_RepetitionCounter = 0x0000,
|
||||
},
|
||||
|
||||
.timerCh1 = 1,
|
||||
.streamCh1 = DMA2_Stream1,
|
||||
.timerCh2 = 3,
|
||||
.streamCh2 = DMA2_Stream6,
|
||||
.streamUpdate = DMA2_Stream5,
|
||||
|
||||
// DMA streamCh1, triggered by timerCh1 pwm signal.
|
||||
// if FrameBuffer indicates, reset output value early to indicate "0" bit to ws2812
|
||||
.dmaInitCh1 = PIOS_WS2811_DMA_CH1_CONFIG(DMA_Channel_6),
|
||||
.dmaItCh1 = DMA_IT_TEIF1 | DMA_IT_TCIF1,
|
||||
|
||||
// DMA streamCh2, triggered by timerCh2 pwm signal.
|
||||
// Reset output value late to indicate "1" bit to ws2812.
|
||||
.dmaInitCh2 = PIOS_WS2811_DMA_CH2_CONFIG(DMA_Channel_6),
|
||||
.dmaItCh2 = DMA_IT_TEIF6 | DMA_IT_TCIF6,
|
||||
|
||||
// DMA streamUpdate Triggered by timer update event
|
||||
// Outputs a high logic level at beginning of a cycle
|
||||
.dmaInitUpdate = PIOS_WS2811_DMA_UPDATE_CONFIG(DMA_Channel_6),
|
||||
.dmaItUpdate = DMA_IT_TEIF5 | DMA_IT_TCIF5,
|
||||
.dmaSource = TIM_DMA_CC1 | TIM_DMA_CC3 | TIM_DMA_Update,
|
||||
|
||||
// DMAInitCh1 interrupt vector, used to block timer at end of framebuffer transfer
|
||||
.irq = {
|
||||
.flags = (DMA_IT_TCIF1),
|
||||
.init = {
|
||||
.NVIC_IRQChannel = DMA2_Stream1_IRQn,
|
||||
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST,
|
||||
.NVIC_IRQChannelSubPriority = 0,
|
||||
.NVIC_IRQChannelCmd = ENABLE,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
void PIOS_WS2811_irq_handler(void)
|
||||
{
|
||||
PIOS_WS2811_DMA_irq_handler();
|
||||
}
|
||||
#endif // PIOS_INCLUDE_WS2811
|
||||
|
@ -53,6 +53,8 @@ MODULES += Telemetry
|
||||
|
||||
OPTMODULES += ComUsbBridge
|
||||
|
||||
SRC += $(FLIGHTLIB)/notification.c
|
||||
|
||||
# Include all camera options
|
||||
CDEFS += -DUSE_INPUT_LPF -DUSE_GIMBAL_LPF -DUSE_GIMBAL_FF
|
||||
|
||||
@ -96,7 +98,9 @@ endif
|
||||
|
||||
# Optional component libraries
|
||||
include $(FLIGHTLIB)/rscode/library.mk
|
||||
|
||||
#include $(FLIGHTLIB)/PyMite/pymite.mk
|
||||
|
||||
|
||||
include $(ROOT_DIR)/make/apps-defs.mk
|
||||
include $(ROOT_DIR)/make/common-defs.mk
|
||||
|
@ -89,6 +89,8 @@
|
||||
#define PIOS_INCLUDE_ETASV3
|
||||
#define PIOS_INCLUDE_MS4525DO
|
||||
|
||||
#define PIOS_INCLUDE_WS2811
|
||||
|
||||
/* #define PIOS_INCLUDE_HCSR04 */
|
||||
|
||||
/* PIOS receiver drivers */
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <oplinkreceiver.h>
|
||||
#include <pios_oplinkrcvr_priv.h>
|
||||
#include <taskinfo.h>
|
||||
#include <pios_ws2811.h>
|
||||
|
||||
/*
|
||||
* Pull in the board-specific static HW definitions.
|
||||
@ -945,6 +946,17 @@ void PIOS_Board_Init(void)
|
||||
PIOS_MPU6000_Init(pios_spi_gyro_id, 0, &pios_mpu6000_cfg);
|
||||
PIOS_MPU6000_CONFIG_Configure();
|
||||
#endif
|
||||
|
||||
#ifdef PIOS_INCLUDE_WS2811
|
||||
#include <pios_ws2811.h>
|
||||
HwSettingsWS2811LED_OutOptions ws2811_pin_settings;
|
||||
HwSettingsWS2811LED_OutGet(&ws2811_pin_settings);
|
||||
|
||||
if (ws2811_pin_settings != HWSETTINGS_WS2811LED_OUT_DISABLED && ws2811_pin_settings < NELEMENTS(pios_ws2811_pin_cfg)) {
|
||||
PIOS_WS2811_Init(&pios_ws2811_cfg, &pios_ws2811_pin_cfg[ws2811_pin_settings]);
|
||||
}
|
||||
|
||||
#endif // PIOS_INCLUDE_WS2811
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,6 +50,8 @@ MODULES += Osd/osdoutout
|
||||
MODULES += Logging
|
||||
MODULES += Telemetry
|
||||
|
||||
SRC += $(FLIGHTLIB)/notification.c
|
||||
|
||||
OPTMODULES += ComUsbBridge
|
||||
|
||||
# Include all camera options
|
||||
|
@ -45,6 +45,8 @@ MODULES += Airspeed
|
||||
#MODULES += AltitudeHold # now integrated in Stabilization
|
||||
#MODULES += OveroSync
|
||||
|
||||
SRC += $(FLIGHTLIB)/notification.c
|
||||
|
||||
# Paths
|
||||
OPSYSTEM = .
|
||||
BOARDINC = ..
|
||||
@ -103,6 +105,8 @@ SRC += $(PIOSCORECOMMON)/pios_dosfs_logfs.c
|
||||
SRC += $(PIOSCORECOMMON)/pios_debuglog.c
|
||||
SRC += $(PIOSCORECOMMON)/pios_callbackscheduler.c
|
||||
SRC += $(PIOSCORECOMMON)/pios_deltatime.c
|
||||
SRC += $(PIOSCORECOMMON)/pios_notify.c
|
||||
|
||||
|
||||
## PIOS Hardware
|
||||
include $(PIOS)/posix/library.mk
|
||||
|
@ -82,13 +82,34 @@ MyTabbedStackWidget::MyTabbedStackWidget(QWidget *parent, bool isVertical, bool
|
||||
|
||||
void MyTabbedStackWidget::insertTab(const int index, QWidget *tab, const QIcon &icon, const QString &label)
|
||||
{
|
||||
tab->setContentsMargins(0, 0, 0, 0);
|
||||
m_stackWidget->insertWidget(index, tab);
|
||||
// create and insert item
|
||||
QListWidgetItem *item = new QListWidgetItem(icon, label);
|
||||
|
||||
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
|
||||
item->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
||||
item->setToolTip(label);
|
||||
m_listWidget->insertItem(index, item);
|
||||
|
||||
// setup and insert widget
|
||||
tab->setContentsMargins(0, 0, 0, 0);
|
||||
m_stackWidget->insertWidget(index, tab);
|
||||
}
|
||||
|
||||
void MyTabbedStackWidget::replaceTab(int index, QWidget *tab)
|
||||
{
|
||||
QWidget *wid = m_stackWidget->widget(index);
|
||||
|
||||
// setup and insert new widget
|
||||
tab->setContentsMargins(0, 0, 0, 0);
|
||||
m_stackWidget->insertWidget(index, tab);
|
||||
// check special case when replacing currenlty selected tab
|
||||
if (index == currentIndex()) {
|
||||
// currently selected tab is being replaced so select the new tab before removing the old one
|
||||
m_stackWidget->setCurrentWidget(tab);
|
||||
}
|
||||
// remove and delete old widget
|
||||
m_stackWidget->removeWidget(wid);
|
||||
delete wid;
|
||||
}
|
||||
|
||||
void MyTabbedStackWidget::removeTab(int index)
|
||||
@ -97,6 +118,7 @@ void MyTabbedStackWidget::removeTab(int index)
|
||||
|
||||
m_stackWidget->removeWidget(wid);
|
||||
delete wid;
|
||||
|
||||
QListWidgetItem *item = m_listWidget->item(index);
|
||||
m_listWidget->removeItemWidget(item);
|
||||
delete item;
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
MyTabbedStackWidget(QWidget *parent = 0, bool isVertical = false, bool iconAbove = true);
|
||||
|
||||
void insertTab(int index, QWidget *tab, const QIcon &icon, const QString &label);
|
||||
void replaceTab(int index, QWidget *tab);
|
||||
void removeTab(int index);
|
||||
void setIconSize(int size)
|
||||
{
|
||||
|
73
ground/openpilotgcs/src/plugins/config/channelform.cpp
Normal file
73
ground/openpilotgcs/src/plugins/config/channelform.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "channelform.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
|
||||
|
||||
ChannelForm::ChannelForm(const int index, QWidget *parent) : ConfigTaskWidget(parent), m_index(index)
|
||||
{}
|
||||
|
||||
ChannelForm::~ChannelForm()
|
||||
{}
|
||||
|
||||
int ChannelForm::index() const
|
||||
{
|
||||
return m_index;
|
||||
}
|
||||
|
||||
void ChannelForm::moveTo(QGridLayout &dstLayout)
|
||||
{
|
||||
QGridLayout *srcLayout = dynamic_cast<QGridLayout *>(layout());
|
||||
|
||||
Q_ASSERT(srcLayout);
|
||||
|
||||
// if we are the first row to be inserted then show the legend
|
||||
bool showLegend = (dstLayout.rowCount() == 1);
|
||||
|
||||
if (showLegend) {
|
||||
// move legend row to target grid layout
|
||||
moveRow(0, *srcLayout, dstLayout);
|
||||
} else {
|
||||
removeRow(0, *srcLayout);
|
||||
}
|
||||
|
||||
// move field row to target grid layout
|
||||
moveRow(1, *srcLayout, dstLayout);
|
||||
|
||||
// this form is now empty so hide it
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void ChannelForm::moveRow(int row, QGridLayout &srcLayout, QGridLayout &dstLayout)
|
||||
{
|
||||
int dstRow = dstLayout.rowCount();
|
||||
|
||||
for (int col = 0; col < srcLayout.columnCount(); col++) {
|
||||
QLayoutItem *item = srcLayout.itemAtPosition(row, col);
|
||||
if (!item) {
|
||||
continue;
|
||||
}
|
||||
QWidget *widget = item->widget();
|
||||
if (widget) {
|
||||
dstLayout.addWidget(widget, dstRow, col);
|
||||
continue;
|
||||
}
|
||||
// TODO handle item of type QLayout
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelForm::removeRow(int row, QGridLayout &layout)
|
||||
{
|
||||
for (int col = 0; col < layout.columnCount(); col++) {
|
||||
QLayoutItem *item = layout.itemAtPosition(row, col);
|
||||
if (!item) {
|
||||
continue;
|
||||
}
|
||||
QWidget *widget = item->widget();
|
||||
if (widget) {
|
||||
layout.removeWidget(widget);
|
||||
delete widget;
|
||||
continue;
|
||||
}
|
||||
// TODO handle item of type QLayout
|
||||
}
|
||||
}
|
36
ground/openpilotgcs/src/plugins/config/channelform.h
Normal file
36
ground/openpilotgcs/src/plugins/config/channelform.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef CHANNELFORM_H
|
||||
#define CHANNELFORM_H
|
||||
|
||||
#include "configtaskwidget.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class ChannelForm;
|
||||
}
|
||||
|
||||
class QGridLayout;
|
||||
|
||||
class ChannelForm : public ConfigTaskWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ChannelForm(const int index, QWidget *parent = 0);
|
||||
~ChannelForm();
|
||||
|
||||
int index() const;
|
||||
|
||||
virtual QString name() = 0;
|
||||
virtual void setName(const QString &name) = 0;
|
||||
|
||||
void moveTo(QGridLayout &dstLayout);
|
||||
|
||||
private:
|
||||
// Channel index
|
||||
int m_index;
|
||||
|
||||
static void moveRow(int row, QGridLayout &srcLayout, QGridLayout &dstLayout);
|
||||
static void removeRow(int row, QGridLayout &layout);
|
||||
};
|
||||
|
||||
#endif // CHANNELFORM_H
|
@ -1,18 +1,19 @@
|
||||
TEMPLATE = lib
|
||||
TARGET = Config
|
||||
DEFINES += CONFIG_LIBRARY
|
||||
QT += svg
|
||||
QT += opengl
|
||||
QT += qml quick
|
||||
|
||||
QT += svg opengl qml quick
|
||||
|
||||
include(config_dependencies.pri)
|
||||
|
||||
INCLUDEPATH += ../../libs/eigen
|
||||
|
||||
OTHER_FILES += Config.pluginspec \
|
||||
OTHER_FILES += \
|
||||
Config.pluginspec \
|
||||
calibration/WizardStepIndicator.qml
|
||||
|
||||
HEADERS += configplugin.h \
|
||||
HEADERS += \
|
||||
configplugin.h \
|
||||
configgadgetwidget.h \
|
||||
configgadgetfactory.h \
|
||||
configgadget.h \
|
||||
@ -27,6 +28,7 @@ HEADERS += configplugin.h \
|
||||
assertions.h \
|
||||
defaultattitudewidget.h \
|
||||
defaulthwsettingswidget.h \
|
||||
channelform.h \
|
||||
inputchannelform.h \
|
||||
configcamerastabilizationwidget.h \
|
||||
configtxpidwidget.h \
|
||||
@ -57,7 +59,8 @@ HEADERS += configplugin.h \
|
||||
calibration/gyrobiascalibrationmodel.h \
|
||||
calibration/calibrationuiutils.h
|
||||
|
||||
SOURCES += configplugin.cpp \
|
||||
SOURCES += \
|
||||
configplugin.cpp \
|
||||
configgadgetwidget.cpp \
|
||||
configgadgetfactory.cpp \
|
||||
configgadget.cpp \
|
||||
@ -71,6 +74,7 @@ SOURCES += configplugin.cpp \
|
||||
configpipxtremewidget.cpp \
|
||||
defaultattitudewidget.cpp \
|
||||
defaulthwsettingswidget.cpp \
|
||||
channelform.cpp \
|
||||
inputchannelform.cpp \
|
||||
configcamerastabilizationwidget.cpp \
|
||||
configrevowidget.cpp \
|
||||
@ -95,7 +99,8 @@ SOURCES += configplugin.cpp \
|
||||
calibration/levelcalibrationmodel.cpp \
|
||||
calibration/gyrobiascalibrationmodel.cpp
|
||||
|
||||
FORMS += airframe.ui \
|
||||
FORMS += \
|
||||
airframe.ui \
|
||||
airframe_ccpm.ui \
|
||||
airframe_fixedwing.ui \
|
||||
airframe_ground.ui \
|
||||
|
@ -55,69 +55,67 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
|
||||
ftw = new MyTabbedStackWidget(this, true, true);
|
||||
ftw->setIconSize(64);
|
||||
stackWidget = new MyTabbedStackWidget(this, true, true);
|
||||
stackWidget->setIconSize(64);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(ftw);
|
||||
layout->addWidget(stackWidget);
|
||||
setLayout(layout);
|
||||
|
||||
// *********************
|
||||
QWidget *qwd;
|
||||
|
||||
QIcon *icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
qwd = new DefaultHwSettingsWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString("Hardware"));
|
||||
stackWidget->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString("Hardware"));
|
||||
|
||||
icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/vehicle_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/vehicle_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
qwd = new ConfigVehicleTypeWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::aircraft, qwd, *icon, QString("Vehicle"));
|
||||
stackWidget->insertTab(ConfigGadgetWidget::aircraft, qwd, *icon, QString("Vehicle"));
|
||||
|
||||
icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/input_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/input_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
qwd = new ConfigInputWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::input, qwd, *icon, QString("Input"));
|
||||
stackWidget->insertTab(ConfigGadgetWidget::input, qwd, *icon, QString("Input"));
|
||||
|
||||
icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/output_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/output_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
qwd = new ConfigOutputWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::output, qwd, *icon, QString("Output"));
|
||||
stackWidget->insertTab(ConfigGadgetWidget::output, qwd, *icon, QString("Output"));
|
||||
|
||||
icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
qwd = new DefaultAttitudeWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("Attitude"));
|
||||
stackWidget->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("Attitude"));
|
||||
|
||||
icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/stabilization_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/stabilization_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
qwd = new ConfigStabilizationWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::stabilization, qwd, *icon, QString("Stabilization"));
|
||||
stackWidget->insertTab(ConfigGadgetWidget::stabilization, qwd, *icon, QString("Stabilization"));
|
||||
|
||||
icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/camstab_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/camstab_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
qwd = new ConfigCameraStabilizationWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::camerastabilization, qwd, *icon, QString("Gimbal"));
|
||||
stackWidget->insertTab(ConfigGadgetWidget::camerastabilization, qwd, *icon, QString("Gimbal"));
|
||||
|
||||
icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/txpid_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/txpid_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
qwd = new ConfigTxPIDWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::txpid, qwd, *icon, QString("TxPID"));
|
||||
stackWidget->insertTab(ConfigGadgetWidget::txpid, qwd, *icon, QString("TxPID"));
|
||||
|
||||
stackWidget->setCurrentIndex(ConfigGadgetWidget::hardware);
|
||||
|
||||
ftw->setCurrentIndex(ConfigGadgetWidget::hardware);
|
||||
// *********************
|
||||
// Listen to autopilot connection events
|
||||
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
TelemetryManager *telMngr = pm->getObject<TelemetryManager>();
|
||||
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
|
||||
@ -129,9 +127,9 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
|
||||
}
|
||||
|
||||
help = 0;
|
||||
connect(ftw, SIGNAL(currentAboutToShow(int, bool *)), this, SLOT(tabAboutToChange(int, bool *)));
|
||||
connect(stackWidget, SIGNAL(currentAboutToShow(int, bool *)), this, SLOT(tabAboutToChange(int, bool *)));
|
||||
|
||||
// Connect to the PipXStatus object updates
|
||||
// Connect to the OPLinkStatus object updates
|
||||
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
||||
oplinkStatusObj = dynamic_cast<UAVDataObject *>(objManager->getObject("OPLinkStatus"));
|
||||
if (oplinkStatusObj != NULL) {
|
||||
@ -148,13 +146,13 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
|
||||
|
||||
ConfigGadgetWidget::~ConfigGadgetWidget()
|
||||
{
|
||||
// TODO: properly delete all the tabs in ftw before exiting
|
||||
delete stackWidget;
|
||||
}
|
||||
|
||||
void ConfigGadgetWidget::startInputWizard()
|
||||
{
|
||||
ftw->setCurrentIndex(ConfigGadgetWidget::input);
|
||||
ConfigInputWidget *inputWidget = dynamic_cast<ConfigInputWidget *>(ftw->getWidget(ConfigGadgetWidget::input));
|
||||
stackWidget->setCurrentIndex(ConfigGadgetWidget::input);
|
||||
ConfigInputWidget *inputWidget = dynamic_cast<ConfigInputWidget *>(stackWidget->getWidget(ConfigGadgetWidget::input));
|
||||
Q_ASSERT(inputWidget);
|
||||
inputWidget->startInputWizard();
|
||||
}
|
||||
@ -166,24 +164,12 @@ void ConfigGadgetWidget::resizeEvent(QResizeEvent *event)
|
||||
|
||||
void ConfigGadgetWidget::onAutopilotDisconnect()
|
||||
{
|
||||
int selectedIndex = ftw->currentIndex();
|
||||
|
||||
QIcon *icon = new QIcon();
|
||||
|
||||
icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
QWidget *qwd = new DefaultAttitudeWidget(this);
|
||||
ftw->removeTab(ConfigGadgetWidget::sensors);
|
||||
ftw->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("Attitude"));
|
||||
|
||||
icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
qwd = new DefaultHwSettingsWidget(this);
|
||||
ftw->removeTab(ConfigGadgetWidget::hardware);
|
||||
ftw->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString("Hardware"));
|
||||
stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd);
|
||||
|
||||
ftw->setCurrentIndex(selectedIndex);
|
||||
qwd = new DefaultHwSettingsWidget(this);
|
||||
stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd);
|
||||
|
||||
emit autopilotDisconnected();
|
||||
}
|
||||
@ -196,45 +182,25 @@ void ConfigGadgetWidget::onAutopilotConnect()
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
|
||||
if (utilMngr) {
|
||||
int selectedIndex = ftw->currentIndex();
|
||||
int board = utilMngr->getBoardModel();
|
||||
if ((board & 0xff00) == 1024) {
|
||||
// CopterControl family
|
||||
|
||||
QIcon *icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
QWidget *qwd = new ConfigCCAttitudeWidget(this);
|
||||
ftw->removeTab(ConfigGadgetWidget::sensors);
|
||||
ftw->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("Attitude"));
|
||||
stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd);
|
||||
|
||||
icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
qwd = new ConfigCCHWWidget(this);
|
||||
ftw->removeTab(ConfigGadgetWidget::hardware);
|
||||
ftw->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString("Hardware"));
|
||||
qwd = new ConfigCCHWWidget(this);
|
||||
stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd);
|
||||
} else if ((board & 0xff00) == 0x0900) {
|
||||
// Revolution family
|
||||
|
||||
QIcon *icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
QWidget *qwd = new ConfigRevoWidget(this);
|
||||
ftw->removeTab(ConfigGadgetWidget::sensors);
|
||||
ftw->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("Attitude"));
|
||||
stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd);
|
||||
|
||||
icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
qwd = new ConfigRevoHWWidget(this);
|
||||
ftw->removeTab(ConfigGadgetWidget::hardware);
|
||||
ftw->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString("Hardware"));
|
||||
qwd = new ConfigRevoHWWidget(this);
|
||||
stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd);
|
||||
} else {
|
||||
// Unknown board
|
||||
qDebug() << "Unknown board " << board;
|
||||
}
|
||||
ftw->setCurrentIndex(selectedIndex);
|
||||
}
|
||||
|
||||
emit autopilotConnected();
|
||||
@ -244,7 +210,7 @@ void ConfigGadgetWidget::tabAboutToChange(int i, bool *proceed)
|
||||
{
|
||||
Q_UNUSED(i);
|
||||
*proceed = true;
|
||||
ConfigTaskWidget *wid = qobject_cast<ConfigTaskWidget *>(ftw->currentWidget());
|
||||
ConfigTaskWidget *wid = qobject_cast<ConfigTaskWidget *>(stackWidget->currentWidget());
|
||||
if (!wid) {
|
||||
return;
|
||||
}
|
||||
@ -275,7 +241,7 @@ void ConfigGadgetWidget::updateOPLinkStatus(UAVObject *)
|
||||
icon->addFile(":/configgadget/images/pipx-selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
|
||||
QWidget *qwd = new ConfigPipXtremeWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::oplink, qwd, *icon, QString("OPLink"));
|
||||
stackWidget->insertTab(ConfigGadgetWidget::oplink, qwd, *icon, QString("OPLink"));
|
||||
oplinkConnected = true;
|
||||
}
|
||||
}
|
||||
@ -284,6 +250,10 @@ void ConfigGadgetWidget::onOPLinkDisconnect()
|
||||
{
|
||||
qDebug() << "ConfigGadgetWidget onOPLinkDisconnect";
|
||||
oplinkTimeout->stop();
|
||||
ftw->removeTab(ConfigGadgetWidget::oplink);
|
||||
oplinkConnected = false;
|
||||
|
||||
if (stackWidget->currentIndex() == ConfigGadgetWidget::oplink) {
|
||||
stackWidget->setCurrentIndex(0);
|
||||
}
|
||||
stackWidget->removeTab(ConfigGadgetWidget::oplink);
|
||||
}
|
||||
|
@ -65,7 +65,6 @@ signals:
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
MyTabbedStackWidget *ftw;
|
||||
|
||||
private:
|
||||
UAVDataObject *oplinkStatusObj;
|
||||
@ -73,6 +72,8 @@ private:
|
||||
// A timer that timesout the connction to the OPLink.
|
||||
QTimer *oplinkTimeout;
|
||||
bool oplinkConnected;
|
||||
|
||||
MyTabbedStackWidget *stackWidget;
|
||||
};
|
||||
|
||||
#endif // CONFIGGADGETWIDGET_H
|
||||
|
@ -80,41 +80,46 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
|
||||
unsigned int indexRT = 0;
|
||||
foreach(QString name, manualSettingsObj->getField("ChannelNumber")->getElementNames()) {
|
||||
Q_ASSERT(index < ManualControlSettings::CHANNELGROUPS_NUMELEM);
|
||||
InputChannelForm *inpForm = new InputChannelForm(this, index == 0);
|
||||
ui->channelSettings->layout()->addWidget(inpForm); // Add the row to the UI
|
||||
inpForm->setName(name);
|
||||
InputChannelForm *form = new InputChannelForm(index, this);
|
||||
form->setName(name);
|
||||
form->moveTo(*(ui->channelLayout));
|
||||
|
||||
// The order of the following binding calls is important. Since the values will be populated
|
||||
// in reverse order of the binding order otherwise the 'Reversed' logic will floor the neutral value
|
||||
// to the max value ( which is smaller than the neutral value when reversed ) and the channel number
|
||||
// will not be set correctly.
|
||||
addWidgetBinding("ManualControlSettings", "ChannelNumber", inpForm->ui->channelNumber, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelGroups", inpForm->ui->channelGroup, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelNeutral", inpForm->ui->channelNeutral, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelNeutral", inpForm->ui->neutralValue, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelMax", inpForm->ui->channelMax, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelMin", inpForm->ui->channelMin, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelMax", inpForm->ui->channelMax, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelNumber", form->ui->channelNumber, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelGroups", form->ui->channelGroup, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelNeutral", form->ui->channelNeutral, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelNeutral", form->ui->neutralValue, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelMax", form->ui->channelMax, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelMin", form->ui->channelMin, index);
|
||||
addWidgetBinding("ManualControlSettings", "ChannelMax", form->ui->channelMax, index);
|
||||
|
||||
addWidget(inpForm->ui->channelNumberDropdown);
|
||||
addWidget(inpForm->ui->channelResponseTime);
|
||||
addWidget(inpForm->ui->channelRev);
|
||||
addWidget(form->ui->channelRev);
|
||||
|
||||
// Reversing supported for some channels only
|
||||
bool reversable = ((index == ManualControlSettings::CHANNELGROUPS_THROTTLE) ||
|
||||
(index == ManualControlSettings::CHANNELGROUPS_ROLL) ||
|
||||
(index == ManualControlSettings::CHANNELGROUPS_PITCH) ||
|
||||
(index == ManualControlSettings::CHANNELGROUPS_YAW));
|
||||
form->ui->channelRev->setVisible(reversable);
|
||||
|
||||
// Input filter response time fields supported for some channels only
|
||||
switch (index) {
|
||||
case ManualControlSettings::CHANNELGROUPS_ROLL:
|
||||
case ManualControlSettings::CHANNELGROUPS_PITCH:
|
||||
case ManualControlSettings::CHANNELGROUPS_YAW:
|
||||
case ManualControlSettings::CHANNELGROUPS_COLLECTIVE:
|
||||
case ManualControlSettings::CHANNELGROUPS_ACCESSORY0:
|
||||
case ManualControlSettings::CHANNELGROUPS_ACCESSORY1:
|
||||
case ManualControlSettings::CHANNELGROUPS_ACCESSORY2:
|
||||
addWidgetBinding("ManualControlSettings", "ResponseTime", inpForm->ui->channelResponseTime, indexRT);
|
||||
addWidgetBinding("ManualControlSettings", "ResponseTime", form->ui->channelResponseTime, indexRT);
|
||||
++indexRT;
|
||||
break;
|
||||
case ManualControlSettings::CHANNELGROUPS_THROTTLE:
|
||||
case ManualControlSettings::CHANNELGROUPS_FLIGHTMODE:
|
||||
case ManualControlSettings::CHANNELGROUPS_COLLECTIVE:
|
||||
inpForm->ui->channelResponseTime->setEnabled(false);
|
||||
form->ui->channelResponseTime->setVisible(false);
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(0);
|
||||
|
@ -76,10 +76,12 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
|
||||
// NOTE: we have channel indices from 0 to 9, but the convention for OP is Channel 1 to Channel 10.
|
||||
// Register for ActuatorSettings changes:
|
||||
for (unsigned int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) {
|
||||
OutputChannelForm *form = new OutputChannelForm(i, this, i == 0);
|
||||
OutputChannelForm *form = new OutputChannelForm(i, this);
|
||||
form->moveTo(*(ui->channelLayout));
|
||||
|
||||
connect(ui->channelOutTest, SIGNAL(toggled(bool)), form, SLOT(enableChannelTest(bool)));
|
||||
connect(form, SIGNAL(channelChanged(int, int)), this, SLOT(sendChannelTest(int, int)));
|
||||
ui->channelLayout->addWidget(form);
|
||||
|
||||
addWidget(form->ui.actuatorMin);
|
||||
addWidget(form->ui.actuatorNeutral);
|
||||
addWidget(form->ui.actuatorMax);
|
||||
@ -194,7 +196,7 @@ OutputChannelForm *ConfigOutputWidget::getOutputChannelForm(const int index) con
|
||||
/**
|
||||
* Set the label for a channel output assignement
|
||||
*/
|
||||
void ConfigOutputWidget::assignOutputChannel(UAVDataObject *obj, QString str)
|
||||
void ConfigOutputWidget::assignOutputChannel(UAVDataObject *obj, QString &str)
|
||||
{
|
||||
// FIXME: use signal/ slot approach
|
||||
UAVObjectField *field = obj->getField(str);
|
||||
@ -204,7 +206,7 @@ void ConfigOutputWidget::assignOutputChannel(UAVDataObject *obj, QString str)
|
||||
OutputChannelForm *outputChannelForm = getOutputChannelForm(index);
|
||||
|
||||
if (outputChannelForm) {
|
||||
outputChannelForm->setAssignment(str);
|
||||
outputChannelForm->setName(str);
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,15 +256,15 @@ void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj)
|
||||
// Initialize output forms
|
||||
QList<OutputChannelForm *> outputChannelForms = findChildren<OutputChannelForm *>();
|
||||
foreach(OutputChannelForm * outputChannelForm, outputChannelForms) {
|
||||
outputChannelForm->setAssignment(ChannelDesc[outputChannelForm->index()]);
|
||||
outputChannelForm->setName(ChannelDesc[outputChannelForm->index()]);
|
||||
|
||||
// init min,max,neutral
|
||||
int minValue = actuatorSettingsData.ChannelMin[outputChannelForm->index()];
|
||||
int maxValue = actuatorSettingsData.ChannelMax[outputChannelForm->index()];
|
||||
outputChannelForm->minmax(minValue, maxValue);
|
||||
outputChannelForm->setRange(minValue, maxValue);
|
||||
|
||||
int neutral = actuatorSettingsData.ChannelNeutral[outputChannelForm->index()];
|
||||
outputChannelForm->neutral(neutral);
|
||||
outputChannelForm->setNeutral(neutral);
|
||||
}
|
||||
|
||||
// Get the SpinWhileArmed setting
|
||||
@ -349,10 +351,10 @@ void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj)
|
||||
int minValue = actuatorSettingsData.ChannelMin[outputChannelForm->index()];
|
||||
int maxValue = actuatorSettingsData.ChannelMax[outputChannelForm->index()];
|
||||
|
||||
outputChannelForm->minmax(minValue, maxValue);
|
||||
outputChannelForm->setRange(minValue, maxValue);
|
||||
|
||||
int neutral = actuatorSettingsData.ChannelNeutral[outputChannelForm->index()];
|
||||
outputChannelForm->neutral(neutral);
|
||||
outputChannelForm->setNeutral(neutral);
|
||||
}
|
||||
|
||||
setDirty(dirty);
|
||||
|
@ -47,6 +47,8 @@ public:
|
||||
ConfigOutputWidget(QWidget *parent = 0);
|
||||
~ConfigOutputWidget();
|
||||
|
||||
protected:
|
||||
void enableControls(bool enable);
|
||||
|
||||
private:
|
||||
Ui_OutputWidget *ui;
|
||||
@ -55,14 +57,14 @@ private:
|
||||
|
||||
void updateChannelInSlider(QSlider *slider, QLabel *min, QLabel *max, QCheckBox *rev, int value);
|
||||
|
||||
void assignChannel(UAVDataObject *obj, QString str);
|
||||
void assignOutputChannel(UAVDataObject *obj, QString str);
|
||||
void assignOutputChannel(UAVDataObject *obj, QString &str);
|
||||
OutputChannelForm *getOutputChannelForm(const int index) const;
|
||||
int mccDataRate;
|
||||
|
||||
UAVObject::Metadata accInitialData;
|
||||
|
||||
bool wasItMe;
|
||||
|
||||
private slots:
|
||||
void stopTests();
|
||||
void disableIfNotMe(UAVObject *obj);
|
||||
@ -71,8 +73,6 @@ private slots:
|
||||
void runChannelTests(bool state);
|
||||
void sendChannelTest(int index, int value);
|
||||
void openHelp();
|
||||
protected:
|
||||
void enableControls(bool enable);
|
||||
};
|
||||
|
||||
#endif // ifndef CONFIGOUTPUTWIDGET_H
|
||||
#endif // CONFIGOUTPUTWIDGET_H
|
||||
|
@ -116,8 +116,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>774</width>
|
||||
<height>748</height>
|
||||
<width>772</width>
|
||||
<height>751</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
@ -143,16 +143,16 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<property name="leftMargin">
|
||||
<number>12</number>
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>12</number>
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
@ -162,21 +162,21 @@
|
||||
<widget class="QWidget" name="advancedPage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>12</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>12</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>12</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>12</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="channelSettings">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
<layout class="QGridLayout" name="channelLayout">
|
||||
<property name="horizontalSpacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
@ -198,7 +198,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="4">
|
||||
<item row="0" column="3">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@ -211,14 +211,14 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelDeadband">
|
||||
<property name="text">
|
||||
<string>Roll/Pitch/Yaw stick deadband</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="deadband">
|
||||
<property name="toolTip">
|
||||
<string>Stick deadband in percents of full range (0-10), zero to disable</string>
|
||||
@ -234,22 +234,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>12</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@ -260,7 +244,7 @@
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@ -369,6 +353,12 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="configurationWizard">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>210</width>
|
||||
@ -413,6 +403,12 @@
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>210</width>
|
||||
@ -546,8 +542,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>774</width>
|
||||
<height>748</height>
|
||||
<width>772</width>
|
||||
<height>751</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7" rowstretch="1,0,0,0">
|
||||
@ -2048,8 +2044,8 @@ Setup the flight mode channel on the RC Input tab if you have not done so alread
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>504</width>
|
||||
<height>156</height>
|
||||
<width>772</width>
|
||||
<height>751</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
@ -2238,7 +2234,7 @@ Set to 0 to disable (recommended for soaring fixed wings).</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../coreplugin/core.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/core/images/helpicon.svg</normaloff>:/core/images/helpicon.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
@ -4,69 +4,36 @@
|
||||
#include "manualcontrolsettings.h"
|
||||
#include "gcsreceiver.h"
|
||||
|
||||
InputChannelForm::InputChannelForm(QWidget *parent, bool showlegend) :
|
||||
ConfigTaskWidget(parent),
|
||||
ui(new Ui::InputChannelForm)
|
||||
InputChannelForm::InputChannelForm(const int index, QWidget *parent) :
|
||||
ChannelForm(index, parent), ui(new Ui::InputChannelForm)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
// The first time through the loop, keep the legend. All other times, delete it.
|
||||
if (!showlegend) {
|
||||
layout()->removeWidget(ui->legend0);
|
||||
layout()->removeWidget(ui->legend1);
|
||||
layout()->removeWidget(ui->legend2);
|
||||
layout()->removeWidget(ui->legend3);
|
||||
layout()->removeWidget(ui->legend4);
|
||||
layout()->removeWidget(ui->legend5);
|
||||
layout()->removeWidget(ui->legend6);
|
||||
layout()->removeWidget(ui->legend7);
|
||||
delete ui->legend0;
|
||||
delete ui->legend1;
|
||||
delete ui->legend2;
|
||||
delete ui->legend3;
|
||||
delete ui->legend4;
|
||||
delete ui->legend5;
|
||||
delete ui->legend6;
|
||||
delete ui->legend7;
|
||||
}
|
||||
|
||||
connect(ui->channelMin, SIGNAL(valueChanged(int)), this, SLOT(minMaxUpdated()));
|
||||
connect(ui->channelMax, SIGNAL(valueChanged(int)), this, SLOT(minMaxUpdated()));
|
||||
connect(ui->neutralValue, SIGNAL(valueChanged(int)), this, SLOT(neutralUpdated()));
|
||||
connect(ui->channelGroup, SIGNAL(currentIndexChanged(int)), this, SLOT(groupUpdated()));
|
||||
connect(ui->channelRev, SIGNAL(toggled(bool)), this, SLOT(reversedUpdated()));
|
||||
|
||||
// This is awkward but since we want the UI to be a dropdown but the field is not an enum
|
||||
// it breaks the UAUVObject widget relation of the task gadget. Running the data through
|
||||
// a spin box fixes this
|
||||
connect(ui->channelNumberDropdown, SIGNAL(currentIndexChanged(int)), this, SLOT(channelDropdownUpdated(int)));
|
||||
connect(ui->channelNumber, SIGNAL(valueChanged(int)), this, SLOT(channelNumberUpdated(int)));
|
||||
|
||||
disableMouseWheelEvents();
|
||||
}
|
||||
|
||||
|
||||
InputChannelForm::~InputChannelForm()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void InputChannelForm::setName(QString &name)
|
||||
QString InputChannelForm::name()
|
||||
{
|
||||
return ui->channelName->text();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the channel assignment label.
|
||||
*/
|
||||
void InputChannelForm::setName(const QString &name)
|
||||
{
|
||||
ui->channelName->setText(name);
|
||||
QFontMetrics metrics(ui->channelName->font());
|
||||
int width = metrics.width(name) + 5;
|
||||
foreach(InputChannelForm * form, parent()->findChildren<InputChannelForm *>()) {
|
||||
if (form == this) {
|
||||
continue;
|
||||
}
|
||||
if (form->ui->channelName->minimumSize().width() < width) {
|
||||
form->ui->channelName->setMinimumSize(width, 0);
|
||||
} else {
|
||||
width = form->ui->channelName->minimumSize().width();
|
||||
}
|
||||
}
|
||||
ui->channelName->setMinimumSize(width, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -136,8 +103,8 @@ void InputChannelForm::reversedUpdated()
|
||||
*/
|
||||
void InputChannelForm::groupUpdated()
|
||||
{
|
||||
ui->channelNumberDropdown->clear();
|
||||
ui->channelNumberDropdown->addItem("Disabled");
|
||||
ui->channelNumber->clear();
|
||||
ui->channelNumber->addItem("Disabled");
|
||||
|
||||
quint8 count = 0;
|
||||
|
||||
@ -168,25 +135,6 @@ void InputChannelForm::groupUpdated()
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
ui->channelNumberDropdown->addItem(QString(tr("Chan %1").arg(i + 1)));
|
||||
ui->channelNumber->addItem(QString(tr("Chan %1").arg(i + 1)));
|
||||
}
|
||||
|
||||
ui->channelNumber->setMaximum(count);
|
||||
ui->channelNumber->setMinimum(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the dropdown from the hidden control
|
||||
*/
|
||||
void InputChannelForm::channelDropdownUpdated(int newval)
|
||||
{
|
||||
ui->channelNumber->setValue(newval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the hidden control from the dropdown
|
||||
*/
|
||||
void InputChannelForm::channelNumberUpdated(int newval)
|
||||
{
|
||||
ui->channelNumberDropdown->setCurrentIndex(newval);
|
||||
}
|
||||
|
@ -1,27 +1,32 @@
|
||||
#ifndef INPUTCHANNELFORM_H
|
||||
#define INPUTCHANNELFORM_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "channelform.h"
|
||||
#include "configinputwidget.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class InputChannelForm;
|
||||
}
|
||||
|
||||
class InputChannelForm : public ConfigTaskWidget {
|
||||
class InputChannelForm : public ChannelForm {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InputChannelForm(QWidget *parent = 0, bool showlegend = false);
|
||||
explicit InputChannelForm(const int index, QWidget *parent = NULL);
|
||||
~InputChannelForm();
|
||||
|
||||
friend class ConfigInputWidget;
|
||||
void setName(QString &name);
|
||||
|
||||
virtual QString name();
|
||||
virtual void setName(const QString &name);
|
||||
|
||||
private slots:
|
||||
void minMaxUpdated();
|
||||
void neutralUpdated();
|
||||
void reversedUpdated();
|
||||
void groupUpdated();
|
||||
void channelDropdownUpdated(int);
|
||||
void channelNumberUpdated(int);
|
||||
|
||||
private:
|
||||
Ui::InputChannelForm *ui;
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>828</width>
|
||||
<height>93</height>
|
||||
<width>923</width>
|
||||
<height>51</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -24,268 +24,18 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item row="0" column="5" colspan="2">
|
||||
<widget class="QLabel" name="legend4">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel neutral</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
margin:1px;
|
||||
font:bold;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Neutral</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="8">
|
||||
<widget class="QSpinBox" name="channelMax">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::UpDownArrows</enum>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="12">
|
||||
<widget class="QLabel" name="legend7">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Response time</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
margin:1px;
|
||||
font:bold;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RT</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="10" colspan="2">
|
||||
<widget class="QLabel" name="legend6">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel values are inverted</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
margin:1px;
|
||||
font:bold;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reversed</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="legend0">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel function</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
margin:1px;
|
||||
font:bold;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Function</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="legend1">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel type</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
margin:1px;
|
||||
font:bold;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="legend2">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -298,6 +48,7 @@ font:bold;</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
@ -310,8 +61,8 @@ font:bold;</string>
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
margin:1px;
|
||||
font:bold;</string>
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
@ -324,133 +75,47 @@ font:bold;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="legend3">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
<item row="0" column="4">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel min</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
margin:1px;
|
||||
font:bold;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Min</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="channelName">
|
||||
<item row="1" column="3">
|
||||
<widget class="QSpinBox" name="channelMin">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QComboBox" name="channelNumberDropdown">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>4</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>25</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>90</width>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="maxVisibleItems">
|
||||
<number>7</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="channelGroup">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>6</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QSpinBox" name="channelMin">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::UpDownArrows</enum>
|
||||
@ -463,123 +128,111 @@ font:bold;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="8">
|
||||
<widget class="QLabel" name="legend5">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="channelGroup">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
<width>110</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel max</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
margin:1px;
|
||||
font:bold;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QSlider" name="channelNeutral">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>22</height>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="12">
|
||||
<widget class="QSpinBox" name="channelResponseTime">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<item row="1" column="2">
|
||||
<widget class="QComboBox" name="channelNumber">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>25</height>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="maxVisibleItems">
|
||||
<number>7</number>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="channelName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Text</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="9">
|
||||
<widget class="QSpinBox" name="channelResponseTime">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
@ -598,6 +251,9 @@ even lead to crash. Use with caution.</string>
|
||||
<property name="frame">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::UpDownArrows</enum>
|
||||
</property>
|
||||
@ -606,21 +262,544 @@ even lead to crash. Use with caution.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="10" colspan="2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="legend0">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel function</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Function</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="7">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="8">
|
||||
<widget class="QLabel" name="legend6">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel values are inverted</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reversed</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="9">
|
||||
<widget class="QLabel" name="legend7">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Response time</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RT</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
<widget class="QLabel" name="legend5">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel max</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QLabel" name="legend4">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel neutral</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Neutral</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="legend3">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel min</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Min</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="legend1">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel type</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QSpinBox" name="channelMax">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::UpDownArrows</enum>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSlider" name="channelNeutral">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="neutralValue">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="8">
|
||||
<widget class="QFrame" name="frame_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -633,15 +812,21 @@ even lead to crash. Use with caution.</string>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0" alignment="Qt::AlignHCenter">
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QCheckBox" name="channelRev">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -652,51 +837,8 @@ even lead to crash. Use with caution.</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QSpinBox" name="neutralValue">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QSpinBox" name="channelNumber">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>216</x>
|
||||
<y>26</y>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>channelNumber</tabstop>
|
||||
<tabstop>channelGroup</tabstop>
|
||||
<tabstop>channelNumberDropdown</tabstop>
|
||||
<tabstop>channelMin</tabstop>
|
||||
<tabstop>channelNeutral</tabstop>
|
||||
<tabstop>channelMax</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -122,8 +122,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>676</width>
|
||||
<height>674</height>
|
||||
<width>674</width>
|
||||
<height>677</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
@ -654,41 +654,46 @@ Leave at 50Hz for fixed wing.</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="channelLayout">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
<layout class="QGridLayout" name="channelLayout">
|
||||
<property name="horizontalSpacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="spinningArmed">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>519</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Motors spin at neutral output when armed and throttle below zero (be careful)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
<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>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="spinningArmed">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>519</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Motors spin at neutral output when armed and throttle below zero (be careful)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
|
@ -26,52 +26,24 @@
|
||||
*/
|
||||
|
||||
#include "outputchannelform.h"
|
||||
#include "configoutputwidget.h"
|
||||
|
||||
OutputChannelForm::OutputChannelForm(const int index, QWidget *parent, const bool showLegend) :
|
||||
ConfigTaskWidget(parent),
|
||||
ui(),
|
||||
m_index(index),
|
||||
m_inChannelTest(false)
|
||||
OutputChannelForm::OutputChannelForm(const int index, QWidget *parent) :
|
||||
ChannelForm(index, parent), ui(), m_inChannelTest(false)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
if (!showLegend) {
|
||||
// Remove legend
|
||||
QGridLayout *grid_layout = dynamic_cast<QGridLayout *>(layout());
|
||||
Q_ASSERT(grid_layout);
|
||||
for (int col = 0; col < grid_layout->columnCount(); col++) { // remove every item in first row
|
||||
QLayoutItem *item = grid_layout->itemAtPosition(0, col);
|
||||
if (!item) {
|
||||
continue;
|
||||
}
|
||||
// get widget from layout item
|
||||
QWidget *legend_widget = item->widget();
|
||||
if (!legend_widget) {
|
||||
continue;
|
||||
}
|
||||
// delete widget
|
||||
grid_layout->removeWidget(legend_widget);
|
||||
delete legend_widget;
|
||||
}
|
||||
}
|
||||
|
||||
// The convention for OP is Channel 1 to Channel 10.
|
||||
ui.actuatorNumber->setText(QString("%1:").arg(m_index + 1));
|
||||
ui.actuatorNumber->setText(QString("%1:").arg(index + 1));
|
||||
|
||||
// Register for ActuatorSettings changes:
|
||||
connect(ui.actuatorMin, SIGNAL(editingFinished()),
|
||||
this, SLOT(setChannelRange()));
|
||||
connect(ui.actuatorMax, SIGNAL(editingFinished()),
|
||||
this, SLOT(setChannelRange()));
|
||||
connect(ui.actuatorRev, SIGNAL(toggled(bool)),
|
||||
this, SLOT(reverseChannel(bool)));
|
||||
connect(ui.actuatorMin, SIGNAL(editingFinished()), this, SLOT(setChannelRange()));
|
||||
connect(ui.actuatorMax, SIGNAL(editingFinished()), this, SLOT(setChannelRange()));
|
||||
connect(ui.actuatorRev, SIGNAL(toggled(bool)), this, SLOT(reverseChannel(bool)));
|
||||
// Now connect the channel out sliders to our signal to send updates in test mode
|
||||
connect(ui.actuatorNeutral, SIGNAL(valueChanged(int)),
|
||||
this, SLOT(sendChannelTest(int)));
|
||||
connect(ui.actuatorNeutral, SIGNAL(valueChanged(int)), this, SLOT(sendChannelTest(int)));
|
||||
|
||||
ui.actuatorLink->setChecked(false);
|
||||
connect(ui.actuatorLink, SIGNAL(toggled(bool)),
|
||||
this, SLOT(linkToggled(bool)));
|
||||
connect(ui.actuatorLink, SIGNAL(toggled(bool)), this, SLOT(linkToggled(bool)));
|
||||
|
||||
disableMouseWheelEvents();
|
||||
}
|
||||
@ -81,6 +53,19 @@ OutputChannelForm::~OutputChannelForm()
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
QString OutputChannelForm::name()
|
||||
{
|
||||
return ui.actuatorName->text();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the channel assignment label.
|
||||
*/
|
||||
void OutputChannelForm::setName(const QString &name)
|
||||
{
|
||||
ui.actuatorName->setText(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restrict UI to protect users from accidental misuse.
|
||||
*/
|
||||
@ -149,26 +134,49 @@ void OutputChannelForm::linkToggled(bool state)
|
||||
}
|
||||
}
|
||||
|
||||
int OutputChannelForm::max() const
|
||||
{
|
||||
return ui.actuatorMax->value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set maximal channel value.
|
||||
*/
|
||||
void OutputChannelForm::max(int maximum)
|
||||
void OutputChannelForm::setMax(int maximum)
|
||||
{
|
||||
minmax(ui.actuatorMin->value(), maximum);
|
||||
setRange(ui.actuatorMin->value(), maximum);
|
||||
}
|
||||
|
||||
int OutputChannelForm::min() const
|
||||
{
|
||||
return ui.actuatorMin->value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set minimal channel value.
|
||||
*/
|
||||
void OutputChannelForm::min(int minimum)
|
||||
void OutputChannelForm::setMin(int minimum)
|
||||
{
|
||||
minmax(minimum, ui.actuatorMax->value());
|
||||
setRange(minimum, ui.actuatorMax->value());
|
||||
}
|
||||
|
||||
int OutputChannelForm::neutral() const
|
||||
{
|
||||
return ui.actuatorNeutral->value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set neutral of channel.
|
||||
*/
|
||||
void OutputChannelForm::setNeutral(int value)
|
||||
{
|
||||
ui.actuatorNeutral->setValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set minimal and maximal channel value.
|
||||
*/
|
||||
void OutputChannelForm::minmax(int minimum, int maximum)
|
||||
void OutputChannelForm::setRange(int minimum, int maximum)
|
||||
{
|
||||
ui.actuatorMin->setValue(minimum);
|
||||
ui.actuatorMax->setValue(maximum);
|
||||
@ -180,35 +188,6 @@ void OutputChannelForm::minmax(int minimum, int maximum)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set neutral of channel.
|
||||
*/
|
||||
void OutputChannelForm::neutral(int value)
|
||||
{
|
||||
ui.actuatorNeutral->setValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the channel assignment label.
|
||||
*/
|
||||
void OutputChannelForm::setAssignment(const QString &assignment)
|
||||
{
|
||||
ui.actuatorName->setText(assignment);
|
||||
QFontMetrics metrics(ui.actuatorName->font());
|
||||
int width = metrics.width(assignment) + 1;
|
||||
foreach(OutputChannelForm * form, parent()->findChildren<OutputChannelForm *>()) {
|
||||
if (form == this) {
|
||||
continue;
|
||||
}
|
||||
if (form->ui.actuatorName->minimumSize().width() < width) {
|
||||
form->ui.actuatorName->setMinimumSize(width, 0);
|
||||
} else {
|
||||
width = form->ui.actuatorName->minimumSize().width();
|
||||
}
|
||||
}
|
||||
ui.actuatorName->setMinimumSize(width, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minimum/maximum value of the channel output sliders.
|
||||
* Have to do it here because setMinimum is not a slot.
|
||||
@ -220,7 +199,7 @@ void OutputChannelForm::setChannelRange()
|
||||
{
|
||||
int oldMini = ui.actuatorNeutral->minimum();
|
||||
|
||||
// int oldMaxi = ui.actuatorNeutral->maximum();
|
||||
// int oldMaxi = ui.actuatorNeutral->maximum();
|
||||
|
||||
if (ui.actuatorMin->value() < ui.actuatorMax->value()) {
|
||||
ui.actuatorNeutral->setRange(ui.actuatorMin->value(), ui.actuatorMax->value());
|
||||
@ -234,8 +213,9 @@ void OutputChannelForm::setChannelRange()
|
||||
ui.actuatorNeutral->setValue(ui.actuatorNeutral->minimum());
|
||||
}
|
||||
|
||||
// if (ui.actuatorNeutral->value() == oldMaxi)
|
||||
// ui.actuatorNeutral->setValue(ui.actuatorNeutral->maximum()); // this can be dangerous if it happens to be controlling a motor at the time!
|
||||
// if (ui.actuatorNeutral->value() == oldMaxi)
|
||||
// this can be dangerous if it happens to be controlling a motor at the time!
|
||||
// ui.actuatorNeutral->setValue(ui.actuatorNeutral->maximum());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -252,8 +232,7 @@ void OutputChannelForm::reverseChannel(bool state)
|
||||
return;
|
||||
}
|
||||
|
||||
// Now, swap the min & max values (only on the spinboxes, the slider
|
||||
// does not change!
|
||||
// Now, swap the min & max values (only on the spinboxes, the slider does not change!)
|
||||
int temp = ui.actuatorMax->value();
|
||||
ui.actuatorMax->setValue(ui.actuatorMin->value());
|
||||
ui.actuatorMin->setValue(temp);
|
||||
@ -286,12 +265,14 @@ void OutputChannelForm::sendChannelTest(int value)
|
||||
}
|
||||
|
||||
if (ui.actuatorRev->isChecked()) {
|
||||
value = ui.actuatorMin->value() - value + ui.actuatorMax->value(); // the channel is reversed
|
||||
// the channel is reversed
|
||||
value = ui.actuatorMin->value() - value + ui.actuatorMax->value();
|
||||
}
|
||||
// update the label
|
||||
ui.actuatorValue->setText(QString::number(value));
|
||||
ui.actuatorValue->setValue(value);
|
||||
|
||||
if (ui.actuatorLink->checkState() && parent()) { // the channel is linked to other channels
|
||||
if (ui.actuatorLink->checkState() && parent()) {
|
||||
// the channel is linked to other channels
|
||||
QList<OutputChannelForm *> outputChannelForms = parent()->findChildren<OutputChannelForm *>();
|
||||
// set the linked channels of the parent widget to the same value
|
||||
foreach(OutputChannelForm * outputChannelForm, outputChannelForms) {
|
||||
@ -315,12 +296,13 @@ void OutputChannelForm::sendChannelTest(int value)
|
||||
}
|
||||
|
||||
outputChannelForm->ui.actuatorNeutral->setValue(val);
|
||||
outputChannelForm->ui.actuatorValue->setText(QString::number(val));
|
||||
outputChannelForm->ui.actuatorValue->setValue(val);
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_inChannelTest) {
|
||||
return; // we are not in Test Output mode
|
||||
// we are not in Test Output mode
|
||||
return;
|
||||
}
|
||||
emit channelChanged(index(), value);
|
||||
}
|
||||
|
@ -27,29 +27,32 @@
|
||||
#ifndef OUTPUTCHANNELFORM_H
|
||||
#define OUTPUTCHANNELFORM_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "channelform.h"
|
||||
#include "configoutputwidget.h"
|
||||
#include "ui_outputchannelform.h"
|
||||
#include "configtaskwidget.h"
|
||||
|
||||
class OutputChannelForm : public ConfigTaskWidget {
|
||||
#include <QWidget>
|
||||
|
||||
class OutputChannelForm : public ChannelForm {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OutputChannelForm(const int index, QWidget *parent = NULL, const bool showLegend = false);
|
||||
explicit OutputChannelForm(const int index, QWidget *parent = NULL);
|
||||
~OutputChannelForm();
|
||||
|
||||
friend class ConfigOutputWidget;
|
||||
|
||||
void setAssignment(const QString &assignment);
|
||||
int index() const;
|
||||
virtual QString name();
|
||||
virtual void setName(const QString &name);
|
||||
|
||||
public slots:
|
||||
void max(int maximum);
|
||||
int max() const;
|
||||
void min(int minimum);
|
||||
int min() const;
|
||||
void minmax(int minimum, int maximum);
|
||||
void neutral(int value);
|
||||
void setMin(int minimum);
|
||||
int max() const;
|
||||
void setMax(int maximum);
|
||||
int neutral() const;
|
||||
void setNeutral(int value);
|
||||
void setRange(int minimum, int maximum);
|
||||
void enableChannelTest(bool state);
|
||||
|
||||
signals:
|
||||
@ -57,8 +60,6 @@ signals:
|
||||
|
||||
private:
|
||||
Ui::outputChannelForm ui;
|
||||
/// Channel index
|
||||
int m_index;
|
||||
bool m_inChannelTest;
|
||||
|
||||
private slots:
|
||||
@ -68,23 +69,4 @@ private slots:
|
||||
void setChannelRange();
|
||||
};
|
||||
|
||||
inline int OutputChannelForm::index() const
|
||||
{
|
||||
return m_index;
|
||||
}
|
||||
|
||||
inline int OutputChannelForm::max() const
|
||||
{
|
||||
return ui.actuatorMax->value();
|
||||
}
|
||||
|
||||
inline int OutputChannelForm::min() const
|
||||
{
|
||||
return ui.actuatorMin->value();
|
||||
}
|
||||
|
||||
inline int OutputChannelForm::neutral() const
|
||||
{
|
||||
return ui.actuatorNeutral->value();
|
||||
}
|
||||
#endif // OUTPUTCHANNELFORM_H
|
||||
|
@ -6,39 +6,52 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>825</width>
|
||||
<height>58</height>
|
||||
<width>768</width>
|
||||
<height>51</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item row="0" column="11">
|
||||
<widget class="QLabel" name="legend5">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="legend0">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>45</width>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
@ -48,37 +61,61 @@
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font:bold;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Link</string>
|
||||
<string>Assignment</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="8">
|
||||
<widget class="QSpinBox" name="actuatorMax">
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="legend1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>25</height>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Maximum PWM value, beware of not overdriving your servo.</string>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Min</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4" colspan="2">
|
||||
<item row="0" column="4">
|
||||
<widget class="QLabel" name="legend2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@ -94,6 +131,7 @@ margin:1px;</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
@ -103,7 +141,7 @@ margin:1px;</string>
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font:bold;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -114,10 +152,26 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="legend6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -128,8 +182,15 @@ margin:1px;</string>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
@ -142,7 +203,7 @@ margin:1px;</string>
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font:bold;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -156,13 +217,13 @@ margin:1px;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<item row="0" column="3">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@ -172,10 +233,42 @@ margin:1px;</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="legend0">
|
||||
<item row="1" column="5">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QSpinBox" name="actuatorMin">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -183,37 +276,13 @@ margin:1px;</string>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font:bold;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Assignment</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QSpinBox" name="actuatorMin">
|
||||
<property name="minimumSize">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>25</height>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
@ -222,69 +291,14 @@ margin:1px;</string>
|
||||
<property name="toolTip">
|
||||
<string>Minimum PWM value, beware of not overdriving your servo.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QSlider" name="actuatorNeutral">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="8">
|
||||
<widget class="QLabel" name="legend3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font:bold;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -299,35 +313,154 @@ margin:1px;</string>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>25</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel Number</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
<string>0:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<item row="0" column="6">
|
||||
<widget class="QLabel" name="legend3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="7">
|
||||
<widget class="QLabel" name="legend4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reversed</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="8">
|
||||
<widget class="QLabel" name="legend5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Link</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="actuatorName">
|
||||
@ -340,21 +473,27 @@ margin:1px;</string>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>110</width>
|
||||
<height>25</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
<string>-</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="9">
|
||||
<widget class="QLabel" name="legend4">
|
||||
<item row="1" column="6">
|
||||
<widget class="QSpinBox" name="actuatorMax">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -362,98 +501,133 @@ margin:1px;</string>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font:bold;
|
||||
margin:1px;</string>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reversed</string>
|
||||
<property name="toolTip">
|
||||
<string>Maximum PWM value, beware of not overdriving your servo.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QLabel" name="actuatorValue">
|
||||
<item row="1" column="4">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSlider" name="actuatorNeutral">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="actuatorValue">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::UpDownArrows</enum>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<widget class="QFrame" name="frame_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Current value of slider.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0000</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="legend1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font:bold;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Min</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="9">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -466,13 +640,10 @@ margin:1px;</string>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QCheckBox" name="actuatorRev">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -494,8 +665,14 @@ margin:1px;</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="11">
|
||||
<widget class="QFrame" name="frame_1">
|
||||
<item row="1" column="8">
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>45</width>
|
||||
@ -506,9 +683,12 @@ margin:1px;</string>
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -521,13 +701,10 @@ margin:1px;</string>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0" alignment="Qt::AlignHCenter">
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QCheckBox" name="actuatorLink">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -551,11 +728,6 @@ margin:1px;</string>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>actuatorMin</tabstop>
|
||||
<tabstop>actuatorNeutral</tabstop>
|
||||
<tabstop>actuatorMax</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -270,7 +270,7 @@ void MainWindow::extensionsInitialized()
|
||||
|
||||
// We'll use qApp macro to get the QApplication pointer
|
||||
// and set the style sheet application wide.
|
||||
qDebug() << "Setting application style sheet to:" << style;
|
||||
// qDebug() << "Setting application style sheet to:" << style;
|
||||
qApp->setStyleSheet(style);
|
||||
|
||||
qs->endGroup();
|
||||
|
@ -52,8 +52,9 @@ plugin_uavtalk.depends += plugin_coreplugin
|
||||
# Telemetry plugin
|
||||
SUBDIRS += plugin_telemetry
|
||||
plugin_telemetry.subdir = telemetry
|
||||
plugin_telemetry.depends = plugin_coreplugin
|
||||
plugin_telemetry.depends += plugin_uavobjectutil
|
||||
plugin_telemetry.depends += plugin_uavtalk
|
||||
plugin_telemetry.depends += plugin_coreplugin
|
||||
|
||||
# OPMap UAVGadget
|
||||
plugin_opmap.subdir = opmap
|
||||
@ -98,9 +99,9 @@ macx:contains(QT_VERSION, ^4\\.8\\.0): CONFIG += disable_notify_plugin
|
||||
plugin_uploader.subdir = uploader
|
||||
plugin_uploader.depends = plugin_coreplugin
|
||||
plugin_uploader.depends += plugin_uavobjects
|
||||
plugin_uploader.depends += plugin_uavobjectutil
|
||||
plugin_uploader.depends += plugin_uavtalk
|
||||
plugin_uploader.depends += plugin_opHID
|
||||
plugin_uploader.depends += plugin_uavobjectutil
|
||||
SUBDIRS += plugin_uploader
|
||||
|
||||
# Dial gadget
|
||||
|
@ -1,12 +1,11 @@
|
||||
TEMPLATE = lib
|
||||
TARGET = Telemetry
|
||||
DEFINES += TELEMETRY_LIBRARY
|
||||
|
||||
QT += svg
|
||||
|
||||
include(../../openpilotgcsplugin.pri)
|
||||
include(../../plugins/coreplugin/coreplugin.pri)
|
||||
include(../../libs/version_info/version_info.pri)
|
||||
include(telemetry_dependencies.pri)
|
||||
include(../../libs/version_info/version_info.pri)
|
||||
|
||||
HEADERS += telemetry_global.h \
|
||||
telemetryplugin.h \
|
||||
@ -23,8 +22,6 @@ SOURCES += telemetryplugin.cpp \
|
||||
monitorgadgetfactory.cpp \
|
||||
monitorgadgetoptionspage.cpp
|
||||
|
||||
DEFINES += TELEMETRY_LIBRARY
|
||||
OTHER_FILES += Telemetry.pluginspec
|
||||
|
||||
RESOURCES += telemetry.qrc
|
||||
|
||||
OTHER_FILES += Telemetry.pluginspec
|
||||
|
@ -1,4 +1,4 @@
|
||||
include(../../plugins/uavobjects/uavobjects.pri)
|
||||
include(../../openpilotgcsplugin.pri)
|
||||
include(../../plugins/coreplugin/coreplugin.pri)
|
||||
include(../../plugins/uavobjectutil/uavobjectutil.pri)
|
||||
include(../../plugins/uavtalk/uavtalk.pri)
|
||||
|
||||
|
@ -199,14 +199,14 @@ void UAVObjectField::limitsInitialize(const QString &limits)
|
||||
elementLimits.insert(index, limitList);
|
||||
++index;
|
||||
}
|
||||
foreach(QList<LimitStruct> limitList, elementLimits) {
|
||||
foreach(LimitStruct limit, limitList) {
|
||||
qDebug() << "Limit type" << limit.type << "for board" << limit.board << "for field" << getName();
|
||||
foreach(QVariant var, limit.values) {
|
||||
qDebug() << "value" << var;
|
||||
}
|
||||
}
|
||||
}
|
||||
// foreach(QList<LimitStruct> limitList, elementLimits) {
|
||||
// foreach(LimitStruct limit, limitList) {
|
||||
// qDebug() << "Limit type" << limit.type << "for board" << limit.board << "for field" << getName();
|
||||
// foreach(QVariant var, limit.values) {
|
||||
// qDebug() << "value" << var;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
bool UAVObjectField::isWithinLimits(QVariant var, quint32 index, int board)
|
||||
{
|
||||
@ -811,43 +811,31 @@ bool UAVObjectField::isNumeric()
|
||||
{
|
||||
switch (type) {
|
||||
case INT8:
|
||||
return true;
|
||||
|
||||
break;
|
||||
case INT16:
|
||||
return true;
|
||||
|
||||
break;
|
||||
case INT32:
|
||||
return true;
|
||||
|
||||
break;
|
||||
case UINT8:
|
||||
return true;
|
||||
|
||||
break;
|
||||
case UINT16:
|
||||
return true;
|
||||
|
||||
break;
|
||||
case UINT32:
|
||||
return true;
|
||||
|
||||
break;
|
||||
case FLOAT32:
|
||||
return true;
|
||||
|
||||
break;
|
||||
case ENUM:
|
||||
return false;
|
||||
|
||||
break;
|
||||
case BITFIELD:
|
||||
return true;
|
||||
|
||||
break;
|
||||
case STRING:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool UAVObjectField::isInteger()
|
||||
{
|
||||
switch (type) {
|
||||
case INT8:
|
||||
case INT16:
|
||||
case INT32:
|
||||
case UINT8:
|
||||
case UINT16:
|
||||
case UINT32:
|
||||
return true;
|
||||
|
||||
break;
|
||||
default:
|
||||
@ -858,42 +846,7 @@ bool UAVObjectField::isNumeric()
|
||||
bool UAVObjectField::isText()
|
||||
{
|
||||
switch (type) {
|
||||
case INT8:
|
||||
return false;
|
||||
|
||||
break;
|
||||
case INT16:
|
||||
return false;
|
||||
|
||||
break;
|
||||
case INT32:
|
||||
return false;
|
||||
|
||||
break;
|
||||
case UINT8:
|
||||
return false;
|
||||
|
||||
break;
|
||||
case UINT16:
|
||||
return false;
|
||||
|
||||
break;
|
||||
case UINT32:
|
||||
return false;
|
||||
|
||||
break;
|
||||
case FLOAT32:
|
||||
return false;
|
||||
|
||||
break;
|
||||
case ENUM:
|
||||
return true;
|
||||
|
||||
break;
|
||||
case BITFIELD:
|
||||
return false;
|
||||
|
||||
break;
|
||||
case STRING:
|
||||
return true;
|
||||
|
||||
|
@ -71,6 +71,7 @@ public:
|
||||
quint32 getDataOffset();
|
||||
quint32 getNumBytes();
|
||||
bool isNumeric();
|
||||
bool isInteger();
|
||||
bool isText();
|
||||
QString toString();
|
||||
void toXML(QXmlStreamWriter *xmlWriter);
|
||||
|
@ -58,7 +58,7 @@ void ConfigTaskWidget::addUAVObject(QString objectName, QList<int> *reloadGroups
|
||||
|
||||
void ConfigTaskWidget::addUAVObject(UAVObject *objectName, QList<int> *reloadGroups)
|
||||
{
|
||||
addUAVObject(objectName ? objectName->getName() : QString(""), reloadGroups);
|
||||
addUAVObject(objectName ? objectName->getName() : QString(), reloadGroups);
|
||||
}
|
||||
|
||||
int ConfigTaskWidget::fieldIndexFromElementName(QString objectName, QString fieldName, QString elementName)
|
||||
@ -84,7 +84,7 @@ void ConfigTaskWidget::addWidgetBinding(QString objectName, QString fieldName, Q
|
||||
|
||||
void ConfigTaskWidget::addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, QString elementName)
|
||||
{
|
||||
addWidgetBinding(object ? object->getName() : QString(""), field ? field->getName() : QString(""), widget, elementName);
|
||||
addWidgetBinding(object ? object->getName() : QString(), field ? field->getName() : QString(), widget, elementName);
|
||||
}
|
||||
|
||||
void ConfigTaskWidget::addWidgetBinding(QString objectName, QString fieldName, QWidget *widget, QString elementName, double scale,
|
||||
@ -97,14 +97,14 @@ void ConfigTaskWidget::addWidgetBinding(QString objectName, QString fieldName, Q
|
||||
void ConfigTaskWidget::addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, QString elementName, double scale,
|
||||
bool isLimited, QList<int> *reloadGroupIDs, quint32 instID)
|
||||
{
|
||||
addWidgetBinding(object ? object->getName() : QString(""), field ? field->getName() : QString(""), widget, elementName, scale,
|
||||
addWidgetBinding(object ? object->getName() : QString(), field ? field->getName() : QString(), widget, elementName, scale,
|
||||
isLimited, reloadGroupIDs, instID);
|
||||
}
|
||||
|
||||
void ConfigTaskWidget::addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, int index, double scale,
|
||||
bool isLimited, QList<int> *reloadGroupIDs, quint32 instID)
|
||||
{
|
||||
addWidgetBinding(object ? object->getName() : QString(""), field ? field->getName() : QString(""), widget, index, scale,
|
||||
addWidgetBinding(object ? object->getName() : QString(), field ? field->getName() : QString(), widget, index, scale,
|
||||
isLimited, reloadGroupIDs, instID);
|
||||
}
|
||||
|
||||
@ -146,7 +146,6 @@ void ConfigTaskWidget::doAddWidgetBinding(QString objectName, QString fieldName,
|
||||
binding->setIsEnabled(m_widgetBindingsPerWidget.count(widget) == 0);
|
||||
m_widgetBindingsPerWidget.insert(widget, binding);
|
||||
|
||||
|
||||
if (object) {
|
||||
m_widgetBindingsPerObject.insert(object, binding);
|
||||
if (m_saveButton) {
|
||||
@ -183,9 +182,9 @@ void ConfigTaskWidget::setWidgetBindingObjectEnabled(QString objectName, bool en
|
||||
binding->setIsEnabled(enabled);
|
||||
if (enabled) {
|
||||
if (binding->value().isValid() && !binding->value().isNull()) {
|
||||
setWidgetFromVariant(binding->widget(), binding->value(), binding->scale());
|
||||
setWidgetFromVariant(binding->widget(), binding->value(), binding);
|
||||
} else {
|
||||
setWidgetFromField(binding->widget(), binding->field(), binding->index(), binding->scale(), binding->isLimited());
|
||||
setWidgetFromField(binding->widget(), binding->field(), binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,7 +235,8 @@ void ConfigTaskWidget::onAutopilotDisconnect()
|
||||
invalidateObjects();
|
||||
}
|
||||
|
||||
void ConfigTaskWidget::forceConnectedState() // dynamic widgets don't recieve the connected signal. This should be called instead.
|
||||
// dynamic widgets don't recieve the connected signal. This should be called instead.
|
||||
void ConfigTaskWidget::forceConnectedState()
|
||||
{
|
||||
m_isConnected = true;
|
||||
setDirty(false);
|
||||
@ -261,7 +261,7 @@ void ConfigTaskWidget::populateWidgets()
|
||||
|
||||
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
|
||||
if (binding->isEnabled() && binding->object() != NULL && binding->field() != NULL && binding->widget() != NULL) {
|
||||
setWidgetFromField(binding->widget(), binding->field(), binding->index(), binding->scale(), binding->isLimited());
|
||||
setWidgetFromField(binding->widget(), binding->field(), binding);
|
||||
}
|
||||
}
|
||||
setDirty(dirtyBack);
|
||||
@ -277,7 +277,7 @@ void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj)
|
||||
emit refreshWidgetsValuesRequested();
|
||||
foreach(WidgetBinding * binding, m_widgetBindingsPerObject.values(obj)) {
|
||||
if (binding->isEnabled() && binding->field() != NULL && binding->widget() != NULL) {
|
||||
setWidgetFromField(binding->widget(), binding->field(), binding->index(), binding->scale(), binding->isLimited());
|
||||
setWidgetFromField(binding->widget(), binding->field(), binding);
|
||||
}
|
||||
}
|
||||
setDirty(dirtyBack);
|
||||
@ -357,13 +357,15 @@ void ConfigTaskWidget::forceShadowUpdates()
|
||||
if (!binding->isEnabled()) {
|
||||
continue;
|
||||
}
|
||||
QVariant widgetValue = getVariantFromWidget(binding->widget(), binding->scale(), binding->units());
|
||||
QVariant widgetValue = getVariantFromWidget(binding->widget(), binding);
|
||||
|
||||
foreach(ShadowWidgetBinding * shadow, binding->shadows()) {
|
||||
disconnectWidgetUpdatesToSlot(shadow->widget(), SLOT(widgetsContentsChanged()));
|
||||
|
||||
checkWidgetsLimits(shadow->widget(), binding->field(), binding->index(), shadow->isLimited(), widgetValue, shadow->scale());
|
||||
setWidgetFromVariant(shadow->widget(), widgetValue, shadow->scale());
|
||||
|
||||
WidgetBinding tmpBinding(shadow->widget(), binding->object(), binding->field(), binding->index(), shadow->scale(), shadow->isLimited());
|
||||
setWidgetFromVariant(shadow->widget(), widgetValue, &tmpBinding);
|
||||
|
||||
emit widgetContentsChanged(shadow->widget());
|
||||
connectWidgetUpdatesToSlot(shadow->widget(), SLOT(widgetsContentsChanged()));
|
||||
@ -376,25 +378,23 @@ void ConfigTaskWidget::widgetsContentsChanged()
|
||||
{
|
||||
QWidget *emitter = ((QWidget *)sender());
|
||||
emit widgetContentsChanged(emitter);
|
||||
double scale = 1.0;
|
||||
QVariant value;
|
||||
|
||||
foreach(WidgetBinding * binding, m_widgetBindingsPerWidget.values(emitter)) {
|
||||
if (binding && binding->isEnabled()) {
|
||||
if (binding->widget() == emitter) {
|
||||
scale = binding->scale();
|
||||
checkWidgetsLimits(emitter, binding->field(), binding->index(), binding->isLimited(),
|
||||
getVariantFromWidget(emitter, scale, binding->units()), scale);
|
||||
value = getVariantFromWidget(emitter, binding);
|
||||
checkWidgetsLimits(emitter, binding->field(), binding->index(), binding->isLimited(), value, binding->scale());
|
||||
} else {
|
||||
foreach(ShadowWidgetBinding * shadow, binding->shadows()) {
|
||||
if (shadow->widget() == emitter) {
|
||||
scale = shadow->scale();
|
||||
checkWidgetsLimits(emitter, binding->field(), binding->index(), shadow->isLimited(),
|
||||
getVariantFromWidget(emitter, scale, binding->units()), scale);
|
||||
WidgetBinding tmpBinding(shadow->widget(), binding->object(), binding->field(),
|
||||
binding->index(), shadow->scale(), shadow->isLimited());
|
||||
value = getVariantFromWidget(emitter, &tmpBinding);
|
||||
checkWidgetsLimits(emitter, binding->field(), binding->index(), shadow->isLimited(), value, shadow->scale());
|
||||
}
|
||||
}
|
||||
}
|
||||
value = getVariantFromWidget(emitter, scale, binding->units());
|
||||
binding->setValue(value);
|
||||
|
||||
if (binding->widget() != emitter) {
|
||||
@ -402,7 +402,7 @@ void ConfigTaskWidget::widgetsContentsChanged()
|
||||
|
||||
checkWidgetsLimits(binding->widget(), binding->field(), binding->index(), binding->isLimited(),
|
||||
value, binding->scale());
|
||||
setWidgetFromVariant(binding->widget(), value, binding->scale());
|
||||
setWidgetFromVariant(binding->widget(), value, binding);
|
||||
emit widgetContentsChanged(binding->widget());
|
||||
|
||||
connectWidgetUpdatesToSlot(binding->widget(), SLOT(widgetsContentsChanged()));
|
||||
@ -413,7 +413,8 @@ void ConfigTaskWidget::widgetsContentsChanged()
|
||||
|
||||
checkWidgetsLimits(shadow->widget(), binding->field(), binding->index(), shadow->isLimited(),
|
||||
value, shadow->scale());
|
||||
setWidgetFromVariant(shadow->widget(), value, shadow->scale());
|
||||
WidgetBinding tmp(shadow->widget(), binding->object(), binding->field(), binding->index(), shadow->scale(), shadow->isLimited());
|
||||
setWidgetFromVariant(shadow->widget(), value, &tmp);
|
||||
emit widgetContentsChanged(shadow->widget());
|
||||
|
||||
connectWidgetUpdatesToSlot(shadow->widget(), SLOT(widgetsContentsChanged()));
|
||||
@ -708,7 +709,7 @@ void ConfigTaskWidget::defaultButtonClicked()
|
||||
continue;
|
||||
}
|
||||
UAVDataObject *temp = ((UAVDataObject *)binding->object())->dirtyClone();
|
||||
setWidgetFromField(binding->widget(), temp->getField(binding->field()->getName()), binding->index(), binding->scale(), binding->isLimited());
|
||||
setWidgetFromField(binding->widget(), temp->getField(binding->field()->getName()), binding);
|
||||
}
|
||||
}
|
||||
|
||||
@ -751,7 +752,7 @@ void ConfigTaskWidget::reloadButtonClicked()
|
||||
if (m_realtimeUpdateTimer->isActive()) {
|
||||
binding->object()->requestUpdate();
|
||||
if (binding->widget()) {
|
||||
setWidgetFromField(binding->widget(), binding->field(), binding->index(), binding->scale(), binding->isLimited());
|
||||
setWidgetFromField(binding->widget(), binding->field(), binding);
|
||||
}
|
||||
}
|
||||
m_realtimeUpdateTimer->stop();
|
||||
@ -823,9 +824,14 @@ void ConfigTaskWidget::disconnectWidgetUpdatesToSlot(QWidget *widget, const char
|
||||
}
|
||||
}
|
||||
|
||||
QVariant ConfigTaskWidget::getVariantFromWidget(QWidget *widget, double scale, QString units)
|
||||
QVariant ConfigTaskWidget::getVariantFromWidget(QWidget *widget, WidgetBinding *binding)
|
||||
{
|
||||
double scale = binding->scale();
|
||||
|
||||
if (QComboBox * cb = qobject_cast<QComboBox *>(widget)) {
|
||||
if (binding->isInteger()) {
|
||||
return cb->currentIndex();
|
||||
}
|
||||
return (QString)cb->currentText();
|
||||
} else if (QDoubleSpinBox * cb = qobject_cast<QDoubleSpinBox *>(widget)) {
|
||||
return (double)(cb->value() * scale);
|
||||
@ -837,7 +843,7 @@ QVariant ConfigTaskWidget::getVariantFromWidget(QWidget *widget, double scale, Q
|
||||
return (QString)(cb->isChecked() ? "TRUE" : "FALSE");
|
||||
} else if (QLineEdit * cb = qobject_cast<QLineEdit *>(widget)) {
|
||||
QString value = (QString)cb->displayText();
|
||||
if (units == "hex") {
|
||||
if (binding->units() == "hex") {
|
||||
bool ok;
|
||||
return value.toUInt(&ok, 16);
|
||||
} else {
|
||||
@ -848,11 +854,18 @@ QVariant ConfigTaskWidget::getVariantFromWidget(QWidget *widget, double scale, Q
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, double scale, QString units)
|
||||
bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, WidgetBinding *binding)
|
||||
{
|
||||
double scale = binding->scale();
|
||||
|
||||
if (QComboBox * cb = qobject_cast<QComboBox *>(widget)) {
|
||||
cb->setCurrentIndex(cb->findText(value.toString()));
|
||||
return true;
|
||||
bool ok = true;
|
||||
if (binding->isInteger()) {
|
||||
cb->setCurrentIndex(value.toInt(&ok));
|
||||
} else {
|
||||
cb->setCurrentIndex(cb->findText(value.toString()));
|
||||
}
|
||||
return ok;
|
||||
} else if (QLabel * cb = qobject_cast<QLabel *>(widget)) {
|
||||
if (scale == 0) {
|
||||
cb->setText(value.toString());
|
||||
@ -875,7 +888,7 @@ bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, dou
|
||||
return true;
|
||||
} else if (QLineEdit * cb = qobject_cast<QLineEdit *>(widget)) {
|
||||
if ((scale == 0) || (scale == 1)) {
|
||||
if (units == "hex") {
|
||||
if (binding->units() == "hex") {
|
||||
cb->setText(QString::number(value.toUInt(), 16).toUpper());
|
||||
} else {
|
||||
cb->setText(value.toString());
|
||||
@ -889,24 +902,19 @@ bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, dou
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, double scale)
|
||||
{
|
||||
return setWidgetFromVariant(widget, value, scale, QString(""));
|
||||
}
|
||||
|
||||
bool ConfigTaskWidget::setWidgetFromField(QWidget *widget, UAVObjectField *field, int index, double scale, bool hasLimits)
|
||||
bool ConfigTaskWidget::setWidgetFromField(QWidget *widget, UAVObjectField *field, WidgetBinding *binding)
|
||||
{
|
||||
if (!widget || !field) {
|
||||
return false;
|
||||
}
|
||||
if (QComboBox * cb = qobject_cast<QComboBox *>(widget)) {
|
||||
if (cb->count() == 0) {
|
||||
loadWidgetLimits(cb, field, index, hasLimits, scale);
|
||||
loadWidgetLimits(cb, field, binding->index(), binding->isLimited(), binding->scale());
|
||||
}
|
||||
}
|
||||
QVariant value = field->getValue(index);
|
||||
checkWidgetsLimits(widget, field, index, hasLimits, value, scale);
|
||||
bool result = setWidgetFromVariant(widget, value, scale, field->getUnits());
|
||||
QVariant value = field->getValue(binding->index());
|
||||
checkWidgetsLimits(widget, field, binding->index(), binding->isLimited(), value, binding->scale());
|
||||
bool result = setWidgetFromVariant(widget, value, binding);
|
||||
if (result) {
|
||||
return true;
|
||||
} else {
|
||||
@ -1070,7 +1078,23 @@ QString WidgetBinding::units() const
|
||||
if (m_field) {
|
||||
return m_field->getUnits();
|
||||
}
|
||||
return QString("");
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString WidgetBinding::type() const
|
||||
{
|
||||
if (m_field) {
|
||||
return m_field->getTypeAsString();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool WidgetBinding::isInteger() const
|
||||
{
|
||||
if (m_field) {
|
||||
return m_field->isInteger();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
UAVObject *WidgetBinding::object() const
|
||||
|
@ -69,6 +69,8 @@ public:
|
||||
~WidgetBinding();
|
||||
|
||||
QString units() const;
|
||||
QString type() const;
|
||||
bool isInteger() const;
|
||||
UAVObject *object() const;
|
||||
UAVObjectField *field() const;
|
||||
int index() const;
|
||||
@ -219,11 +221,10 @@ private:
|
||||
QString m_outOfLimitsStyle;
|
||||
QTimer *m_realtimeUpdateTimer;
|
||||
|
||||
bool setWidgetFromField(QWidget *widget, UAVObjectField *field, int index, double scale, bool hasLimits);
|
||||
bool setWidgetFromField(QWidget *widget, UAVObjectField *field, WidgetBinding *binding);
|
||||
|
||||
QVariant getVariantFromWidget(QWidget *widget, double scale, const QString units);
|
||||
bool setWidgetFromVariant(QWidget *widget, QVariant value, double scale, QString units);
|
||||
bool setWidgetFromVariant(QWidget *widget, QVariant value, double scale);
|
||||
QVariant getVariantFromWidget(QWidget *widget, WidgetBinding *binding);
|
||||
bool setWidgetFromVariant(QWidget *widget, QVariant value, WidgetBinding *binding);
|
||||
|
||||
void connectWidgetUpdatesToSlot(QWidget *widget, const char *function);
|
||||
void disconnectWidgetUpdatesToSlot(QWidget *widget, const char *function);
|
||||
|
@ -46,15 +46,14 @@ SOURCES += uploadergadget.cpp \
|
||||
SSP/qsspt.cpp \
|
||||
runningdevicewidget.cpp
|
||||
|
||||
OTHER_FILES += Uploader.pluginspec \
|
||||
OTHER_FILES += Uploader.pluginspec
|
||||
|
||||
FORMS += \
|
||||
uploader.ui \
|
||||
devicewidget.ui \
|
||||
runningdevicewidget.ui
|
||||
|
||||
RESOURCES += \
|
||||
uploader.qrc
|
||||
RESOURCES += uploader.qrc
|
||||
|
||||
exists( ../../../../../build/openpilotgcs-synthetics/opfw_resource.qrc ) {
|
||||
RESOURCES += ../../../../../build/openpilotgcs-synthetics/opfw_resource.qrc
|
||||
|
@ -99,7 +99,7 @@ SRC += $(PIOSCOMMON)/pios_usb_util.c
|
||||
## PIOS system code
|
||||
SRC += $(PIOSCOMMON)/pios_task_monitor.c
|
||||
SRC += $(PIOSCOMMON)/pios_callbackscheduler.c
|
||||
|
||||
SRC += $(PIOSCOMMON)/pios_notify.c
|
||||
## Misc library functions
|
||||
SRC += $(FLIGHTLIB)/fifo_buffer.c
|
||||
SRC += $(FLIGHTLIB)/sanitycheck.c
|
||||
|
@ -4,7 +4,7 @@
|
||||
<field name="SamplePeriod" units="ms" type="uint8" elements="1" defaultvalue="100"/>
|
||||
<field name="ZeroPoint" units="raw" type="uint16" elements="1" defaultvalue="0"/>
|
||||
<field name="Scale" units="raw" type="float" elements="1" defaultvalue="1.0"/>
|
||||
<field name="AirspeedSensorType" units="" type="enum" elements="1" options="PixHawkAirspeedMS4525DO,EagleTreeAirspeedV3,DIYDronesMPXV5004,DIYDronesMPXV7002,GroundSpeedBasedWindEstimation,None" defaultvalue="GroundSpeedBasedWindEstimation"/>
|
||||
<field name="AirspeedSensorType" units="" type="enum" elements="1" options="PixHawkAirspeedMS4525DO,EagleTreeAirspeedV3,DIYDronesMPXV5004,DIYDronesMPXV7002,GroundSpeedBasedWindEstimation,None" defaultvalue="None"/>
|
||||
<field name="GroundSpeedBasedEstimationLowPassAlpha" units="" type="float" elements="1" defaultvalue="0.08" />
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
|
||||
|
@ -25,6 +25,7 @@
|
||||
<field name="OptionalModules" units="" type="enum" elementnames="CameraStab,GPS,ComUsbBridge,Fault,Altitude,Airspeed,TxPID,Autotune,VtolPathFollower,FixedWingPathFollower,Battery,Overo,MagBaro,OsdHk" options="Disabled,Enabled" defaultvalue="Disabled"/>
|
||||
<field name="ADCRouting" units="" type="enum" elementnames="adc0,adc1,adc2,adc3" options="Disabled,BatteryVoltage,BatteryCurrent,AnalogAirspeed,Generic" defaultvalue="Disabled"/>
|
||||
<field name="DSMxBind" units="" type="uint8" elements="1" defaultvalue="0"/>
|
||||
<field name="WS2811LED_Out" units="" type="enum" elements="1" options="ServoOut1,ServoOut2,ServoOut3,ServoOut4,ServoOut5,ServoOut6,FlexiPin3,FlexiPin4,Disabled" defaultvalue="Disabled" />
|
||||
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
|
||||
|
Loading…
Reference in New Issue
Block a user